0

postgres DB に接続する nodeJS にスクリプトがあります。問題は、コールバック メソッドで変数を開始していることですが、常に空のように見えます。これは私の app.js スクリプトです。

var ck_username = /^[A-Za-z0-9_]{1,20}$/;
function fncCheckUsernameAvailability(vstrUsername, callback) {
    var pg = require("pg");
    var client = new pg.Client({user: 'xxx', password: 'xxx', database: 'xxx', host: 'xxx.com'});
    client.connect(function(err) {
    if (err) {
      callback(err, null);
      return;
    }
    client.query("SELECT username FROM users WHERE username ='"+vstrUsername+"'", function(err, result) {
      if (err) {
        callback(err, null);
        return;
      }
      if (result.rows[0] == undefined) {
            callback(null, null);
      }else {
            callback(null, 'Username already taken');
      }
    client.end();
    });
  });
}

app.post("/Signup", function(req, res){
var username = req.body.username;

var usernameError = '';  
var errors = [];

if (!ck_username.test(username)) {
    errors[errors.length] = "Invalid username";
    usernameError = "Invalid username";
} 
if (ck_username.test(username)) {
     //The issue starts here
    fncCheckUsernameAvailability(username, function(err, result) { 
        if(result != null){ 
        errors[errors.length] = result;
            usernameError = result; // usernameError  is always empty 
            console.log(result);//This is printed in console, I can see the result
        }
    });
}
if (errors.length > 0) {
     res.render('Signup.ejs', {
        layout:false,
        usernameError:usernameError // usernameError is sent to the view empty            
    });
}
else{
    res.render('Signup.ejs', {
        layout:false,
        usernameError:'No errors'
    });
} 
});

結果はcansoleに表示されるので、誰かがこの変数がインスタンス化されていない理由を教えてもらえますか?このコールバックは非同期のものですか?

4

2 に答える 2

1

はい、コールバックは非同期で、いつでも実行できます。おそらく、アクセスしている時点ではまだ定義されていません。したがって、コールバック内から変数にアクセスする必要があるため、常にその時点で定義されます。

app.post('/Signup', function (req, res) {
  var username = req.body.username;

  if (!ck_username.test(username)) {
    res.render('Signup.ejs', {
      layout: false,
      usernameError: 'Invalid username'          
    });
  } else {
    fncCheckUsernameAvailability(username, function (err, result) {
      if (result != null) {
        res.render('Signup.ejs', {
          layout: false,
          usernameError: result            
        });
      } else {
        res.render('Signup.ejs', {
          layout: false,
          usernameError: 'No errors'
        });
      }
    });
  }
});

コールバックがどのように機能するか、および変数が期待値を返さなかった理由の例を次に示します。次の 2 つの関数を使用します。

var foo = function(num, callback) {
  setTimeout(function() {
    callback(num * 2);
  }, 5000);
};

この関数は数値を 2 で乗算しますが、5 秒後です。この 5 秒より前に変数にアクセスしようとすると、次のように値がありません。

var num = 0;
foo(5, function(result) {
  num = result;
});

console.log(num); // returns 0

この場合、は5 秒後にnumのみ設定され、その時間が経過する前に実行されます。10console.log()

于 2013-09-13T23:14:06.780 に答える