web-dev-qa-db-fra.com

Node.js Requêtes synchrones avec MySQL

Je travaille sur la création d'un système d'enregistrement des utilisateurs pour un site Web sur lequel je travaille, mais je rencontre quelques problèmes.

J'essaie d'éviter de devoir imbriquer des rappels car cela devient un peu confus. Ce dont j'ai besoin d'aide, c'est de trouver s'il existe un moyen de créer des requêtes synchrones avec node-mysql

Voici ce que j'essaie de réaliser.

connection.query("select 1 as email from users where email = " + connection.escape(email), function(err, rows, fields) {
    if(err) {
        var error = {
            error_message: err.code,
            error_number: err.errno
        };

        return res.send(error);
    }

    if(rows.length > 0) {
        var error = {
            message: 'Email Address is Taken',
            code: 2
        };
        return res.send(error);
    }
});

connection.query("insert into users (email, password) values ("+connection.escape(email)+", "+connection.escape(hash)+")", function(err, rows, fields) {
            if(err) {
                var error = {
                    error_message: err.code,
                    error_number: err.errno
                };

                return res.send(error);
            }
        });

Mon objectif est de faire exécuter la première requête et si cela retourne une ligne, de ne pas exécuter la seconde requête mais si la première requête renvoie 0 ligne, continuez et exécutez la seconde requête.

Je sais que je peux imbriquer la seconde requête à l'intérieur de la première requête et la mettre si dans un autre, mais c'est ce que je ne veux pas faire car, même si j'ai ces deux requêtes, je l'ai également configuré pour utiliser bcrypt pour crypter le mot de passe doivent être imbriqués aussi.

Y a-t-il un moyen de l'écrire pour que je n'aie pas besoin d'imbriquer les deux requêtes ou est-ce que les imbriquer va être ma seule option?

8
Alex Beebe

Comme jfriend00 l’a dit plus haut, si vous envisagez de développer un noeud node.js, vous DEVEZ vous familiariser avec l’écriture de code async.

"promesses chaînées" est probablement votre meilleur pari:

ADDENDA:

Ce didacticiel illustre l’enchaînement des promesses avec les requêtes SQL de node.js. Il explique également comment vous pouvez utiliser Q et/ou Étape pour simplifier votre code:

11
paulsm4

Vous pouvez simplement utiliser un module pour un noeud fournissant des fonctions synchrones. Ici vous trouverez un module qui fournit des fonctions sync/async pour traiter mysql. 

https://github.com/Will-I4M/node-mysql-libmysqlclient

Voici comment vous pouvez l'utiliser pour exécuter une requête synchrone: 

var config = require("./config.json") ;
var mysql = require('mysql-libmysqlclient') ;
var client = mysql.createConnectionSync(config.Host, config.user, config.password, config.database) ;

var query = "SELECT * FROM Users ;" ;
var handle = client.querySync(query) ;
var results = handle.fetchAllSync() ;

console.log(JSON.stringify(results)) ; 
13
will.I4M

Pour la plupart des choses, je code dans node.js, j'aime le code asynchrone. Cependant, je comprends tout à fait que le code asynchrone est extrêmement et dangereusement incompatible avec la nécessité d'écrire et de maintenir la logique métier. J'ai utilisé diverses méthodes alternatives. Les modules pour rendre les choses synchrones vous laissent toujours avec des problèmes de portée de données qui compliquent les choses. Les promesses ont fonctionné le mieux pour moi. En utilisant cette approche, je me suis retrouvé à écrire pratiquement un interprète pour un nouveau langage en plus de JavaScript. Je peux paraître absurde, mais la méthode la plus pratique et la plus sûre pour moi a finalement été d’utiliser le module shelljs et le client mysql Shell. Ce n'est pas une excellente performance d'exécution, mais cela permet d'améliorer considérablement les performances des développeurs et de garder la logique métier claire et ordonnée, ce qui est essentiel pour la logique métier. Voici un extrait de code qui donne un exemple de ce que j'ai créé:

var Shell = require ('shelljs');

module.exports = { utilisateur:'', mot de passe:'',

   runSql:function( sql ) {
            var command = "echo '" + sql.replace(/'/g,"'\\''") + "' | mysql -u" + this.user.replace(/'/g,"'\\''") + " -p'" + this.password.replace(/'/g,"'\\''") + "'";
            var raw = Shell.exec( command, {silent:true} ).stdout;
            //console.log( 'BASH -> MySQL YIELD: "' + raw + '"' );
            if( raw.substr(0,5) === 'ERROR' ) {
                    console.log( 'ERROR Resulting from: ' + sql + '\n' + raw );
                    return [];
            }
            var rows = raw.split('\n');
            var names = [];
            for( var r = 0; r < rows.length; r += 1 ) {
                    columns = rows[r].split('\t'); 

                    // Capture column names
                    if( r === 0 ) {
                            names = columns;
                            continue;
                    }

                    // Reformat row into named valued
                    var fields = {};
                    for( var c = 0; c < columns.length; c += 1 ) {
                            fields[names[c]] = columns[c];
                    }
                    rows[r] = fields;
            };

            // Eliminate extraneous first and last rows
            rows.splice(0,1);
            rows.splice(rows.length-1,1);

            return rows;
    },
1
user1018645

Il peut y avoir des conditions lorsque vous avez besoin de requêtes de synchronisation (ou au moins pour des raisons de lisibilité ou de simplicité). Je ne suis pas d'accord avec le fait que tout doit être fait de manière asynchrone à node.js.

J'ai testé de nombreuses solutions disponibles et fini avec le module "sync-mysql" ( https://github.com/ForbesLindesay/sync-mysql ).

Facile à installer et à utiliser, mais pas très performant (surtout si vous devez faire beaucoup de sous-requêtes).

0
Zoltán Hajdú