8

I'm new to Node.Js and JavaScript web development on the backend. I see that callbacks inside callbacks could be a pain and there are modules to avoid that. One of these modules is async, https://github.com/caolan/async

I've read the documentation but it is hard to start and understand how to do it.

For example, I've this function "check_aut_user", How can I convert this code using async?

function check_auth_user(username, password, done) {

    var client = new pg.Client("pg://user:pass@127.0.0.1/database");
    client.connect(function(err) {
        // If not get the connection
        if(err) { return console.error('could not connect to postgres', err); }

        // Query the user table
        client.query('select * from "user" where username = $1 and password = $2', [username, password], function(err, result) {
            if(err) { return console.error('error running query', err); }

            if (result.rowCount > 0) {
                var res = result.rows[0];
                console.log(res);

                passport.serializeUser(function(res, done) {
                    //console.log("serializer: " + res);
                    done(null, res);
                });

                passport.deserializeUser(function(user, done) {
                    //console.log("deserializer: " + user['password']);
                    done(null, res);
                }); 

                return done(null, res);
            } else {
                return done(null, false);
            }               
        });     
    });
}

Best Regards,

4

3 に答える 3

0

必要に応じて非同期を使用するように変更されたコードを次に示します。

function check_auth_user(username, password) {
    var client = new pg.Client("pg://user:pass@127.0.0.1/database");
    async.waterfall([
      client.connect,
      function(callback) {
        client.query('select * from "user" where username = $1 and password = $2', [username, password], callback);
      },
      function(result, callback) {
        if(result.rowCount > 0) {
                var res = result.rows[0];

                async.series([
                   function(callback) {
                     passport.serializeUser(res, function(res, done) {
                       callback(null, res);
                     }
                   },
                   function(res, callback){
                     if(res) {
                       passport.deserializeUser(res, function(res, done) {
                          callback(null, res);
                       });
                     } else {
                       callback(new Error('SerializeUser failed'));
                     }
                   }
                ], function(err, res) {
                    if(err) {
                       callback(err);
                    } else {
                       callback(null);
                    }
                });
        }
        else {
           callback(new Error("No result"));
        }
      }
    ], function(err, result) {
       if(err)
          console.err(err);
    });
}

明らかに、コードが読みやすくなるわけではありません。追加の変更をお勧めします:

  • データベースへのクエリは独自のメソッドで分離する必要があります (これは実際にはモデル メソッドです)。これにより、独自の「領域」でエラー チェックを行うことができます。
  • Passport のシリアライゼーション/デシリアライゼーションは、同じ理由で別の方法で行う必要があります。

これら 2 つのメソッドは両方ともコールバックを受け取ります。ここに書き直します:

// Given a client, queries for user
function retrieveUser( client, username, password, cb) {
  client.query('select * from "user" where username = $1 and password = $2', [username, password], function(err, users){
    if(err) {
      cb(err);
    }
    else if(users.rowCount < 0) {
      cb(new Error("No user found for username ="+username));
    }
    else {
      cb(null, result.rows[0]);
  });
}

//Uses passport to serialize/deserializeUser
function passportSerialize(user, cb){
      async.series([
       function(callback) {
         passport.serializeUser(user, function(res, done) {
           callback(null, res);
         }
       },
       function(res, callback){
         if(res) {
           passport.deserializeUser(res, function(res, done) {
              if(res) {
                 callback(null, res);
              } else {
                 callback(new Error('deserializeUser failed'));
              } 
           });
         } else {
           callback(new Error('SerializeUser failed'));
         }
       }
    ], cb);
}

したがって、主な方法は次のようになります。

function check_auth_user(username, password) {
    var client = new pg.Client("pg://user:pass@127.0.0.1/database");
    async.waterfall([
      client.connect,
      function(callback) {
        retrieveUser(client, username, password, callback);
      },
      function(user, callback) {
            passportSerialize(user, callback);
      }
    ], function(err, result) {
       if(err)
          console.err(err);
        else
          console.log("User authenticated, let her in");
    });
}

これがどのようにはるかに優れているかを理解していただければ幸いです。

于 2014-01-07T01:20:07.567 に答える