NodeJS 回调变量赋值总是落后一次更新

NodeJS callback variable assignation is always one update behind

我正在学习 NodeJS,我有以下代码:

     var test = '';

    function test2(name,callback) {
     UserData
          .findOne({'token': name})
          .then(function(user) {
            test = user.token;
            console.log('current: '+user.token);
              return callback(user.token);
          })
          .catch(function(err) {
              console.log(err);
          });
    }


var isAuthenticated = function(req,res,next){

  test2(req.cookies.remember_me, function(user) {test=user; });
console.log('test:::: '+test);
  var isLog = false;
  if(req.session.user!= undefined && req.session.user===test){
    isLog=true;

  }
  if(req.cookies.remember_me ===test){
    console.log('test'+test);
    isLog=true;

  }

  if(isLog){
     return 1;

  }else
    {
      console.log('not auth');
      return -1;
    }
}

结果是:

测试::::P9Ysq2oSCHy1RVyWsePxJhpEYLD81qOiIayTyiNJCnOkmllvEspwrDAW8tD9rmfJ

未授权

当前:k8LJcCty6568QpXNS3urBedlJ0MDfEYlbOqo9Q7tQi9EOyeSkyesgHHzUjBhDgZx

我知道这是因为 NodeJS 的异步性质,但我怎样才能使测试始终与 'current';

相同

谢谢。

您犯了一个非常典型的错误,即期望代码按编写顺序 运行,但由于 javascript 的异步性质,这并非如此。例如:

test2(req.cookies.remember_me, function(user) {test=user; });
console.log('test:::: '+test);

此处您的 console.log() 将在回调之前 运行 因为回调只会在您收到 DB 的回复后发生。 (虽然不清楚那个测试值('P9Ysq2oSCH...')是从哪里来的。

只要您正在学习 Node,就应该从尝试避免混淆回调和承诺开始。您的 findOne() 函数 return 是一个承诺,这就是您可以对其调用 then() 的原因。您应该只 return 这个承诺,然后在调用函数中调用 then()

function test2(name) {
    // return is important - you're returning the promise which you will use later.
    return UserData.findOne({'token': name})
        .then(function(user) {
            return user.token;
        })
        .catch(function(err) {
            console.log(err);
        });
    }


function isAuthenticated(req,res,next){
    return test2(req.cookies.remember_me)
    .then(function(token) {
        console.log('test:::: '+token);
        var isLog = false;
        if(req.session.user!= undefined && req.session.user===token){
            isLog=true;
        }
        if(req.cookies.remember_me ===token){
            isLog=true;
        }
        return isLog
    })     
}

// Use the function 
isAuthenticated(req,res,next)
.then(function(isLoggedin){
    if(isLoggedin) {
        // user logged in
    } else {
        // not logged in
    }
})