This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
                                
                                    (6个答案)
                                
                        
                                4年前关闭。
            
                    
我有一个功能,基本上查询MongoDB的凭据(简化):

var query = Credential.findOne({token: token});

return query.exec(function (err, credential) {
    if (err) return null;
    return credential;
});


我需要此credential来进行另一个查询以获取关联的角色:

router.get('/api/roles', function (req, res) {
   var token = req.headers.authorization || '';
   var cred;

   if (token === '') {
       return res.sendStatus(401);
   }
   getCredential(token).then(function (credential) {
      cred = credential;
   });

   getRoles(cred).then(function(roles) {
      return res.json(roles);
   });
});


不幸的是,我似乎无法从已解决的Promise中设置局部变量cred,因此它是undefined。任何想法如何做到这一点?

最佳答案

您似乎不太了解诺言如何异步工作。正在设置您的局部变量,但是直到您使用它为止。执行顺序如下所示:


角色查询完成
获取凭证查询开始
获取角色查询开始
凭证查询完成
角色查询完成


如您所见,凭证和角色查询同时启动。设置cred的回调在凭据查询完成之前不会运行,因此为时已晚。您可以利用承诺来解决此问题。

router.get('/api/roles', function (req, res) {
    var token = req.headers.authorization || '';

    if (token === '') {
        return res.sendStatus(401);
    }

    getCredential(token).then(function (credential) {
        // getRoles returns a promise
        // The next "then()" will be called when this
        // promise is resolved
        return getRoles(credential);
    })
    .then(function(roles) {
        res.json(roles);
    });
});


现在执行如下运行:


角色查询完成
获取凭证查询开始
凭证查询完成
角色查询开始
角色查询完成并设置响应

10-04 16:10
查看更多