【问题标题】:NodeJS callback variable assignation is always one update behindNodeJS 回调变量赋值总是落后一个更新
【发布时间】:2017-10-30 02:28:17
【问题描述】:

我正在学习 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;
    }
}

结果是:

test:::: P9Ysq2oSCHy1RVyWsePxJhpEYLD81qOiIayTyiNJCnOkmllvEspwrDAW8tD9rmfJ

不授权

当前:k8LJcCty6568QpXNS3urBedlJ0MDfEYlbOqo9Q7tQi9EOyeSkyesgHHzUjBhDgZx

我知道这是因为 NodeJS 的异步特性,但是我怎样才能使测试始终与“当前”相同;

谢谢。

【问题讨论】:

  • 您可以从正确缩进代码开始。到目前为止,已经有工具可以为你做这件事,没有任何理由让代码如此混乱。

标签: node.js asynccallback


【解决方案1】:

您犯了一个非常经典的错误,即期望代码按照编写的顺序运行,但这并不是因为 javascript 的异步特性。例如:

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

在这里,您的console.log() 将在回调之前运行,因为回调仅在您收到数据库的回复后才会发生。 (虽然尚不清楚该测试值('P9Ysq2oSCH...')来自何处。

只要您正在学习 Node,就应该从避免混用回调和 Promise 开始。你的findOne() 函数返回一个promise,这就是你可以调用then() 的原因。你应该只返回这个承诺,然后在调用函数中调用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
    }
})

【讨论】:

  • 感谢您的回复。 1.没有测试的初始值,生成的令牌值并在登录时保存。(我重新加载了多次,这就是为什么测试有x值)2.我需要'isAuthenticated'变量来返回类似:-1表示'不好' 如果 remember_me 值与令牌匹配,则 1 表示 'ok'。另外(重要)我需要在同一个函数中多次调用“test2”(最好)。我以前喜欢 NodeJS……这个。也是一个幼稚的解决方法:pastebin.com/WjnAxHHu 今天的教训:不要尝试连续 12 小时学习 NodeJS 哈哈哈。
  • 你无法避免异步问题——没有办法绕过它们。所以你必须拥抱他们。这意味着你不能指望一个依赖异步数据的函数只返回一个值。它需要返回的是承诺或触发回调。一旦你习惯了它确实变得容易。我更新了答案以显示使用它的可能方法。我不确定您将如何使用 test2 进行多次通话,因此我不确定如何提供建议。通常,当您需要一起进行许多异步调用时,您使用 Promise.all()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2021-06-04
  • 2018-06-29
  • 1970-01-01
相关资源
最近更新 更多