JS - 然后等待承诺

时间:2016-06-11 14:10:47

标签: javascript promise

我知道的一个常见话题,但我只想确认我对JS和承诺世界的理解。

所以我有以下代码段失败,因为then块实际上并没有等待上面的段完成。即我没有得到okCheck的最终/正确值。

var okCheck = false;

User.findOne({publicID: id}, function (err, userInfo) {
      if ( userInfo.checked.indexOf(id) > -1 ){
        okCheck = true;
      }
})
.then(function() {
      //do some additional stuff using the boolean okCheck
}

所以要解决这个问题 - 根据我的理解,我需要使用return - 这是正确的吗?

var okCheck = false;

User.findOne({publicID: id}, function (err, userInfo) {
      if ( userInfo.checked.indexOf(id) > -1 ){
        okCheck = true;
      }
      return okCheck;
})
.then(function() {
      //do some additional stuff using the boolean okCheck
}

这是正确的 - 即我保证我总是拥有okCheck的最终价值吗?

感谢。

3 个答案:

答案 0 :(得分:0)

  

根据我的理解,我需要使用return - 这是正确的吗?

是。但return一个值并不会影响与时间相关的任何事情。

关键是来自return回调的then值将是它返回的promise的解析值,并成为链中下一个回调的参数。

您不应该从异步回调中修改外部作用域变量。正确的方法是推迟行动直到承诺得到解决,而不是等待"等待"用于显示变量值的任何内容:

// no `var` here!
User.findOne({publicID: id}).then(function(userInfo) {
    return userInfo.checked.indexOf(id) > -1;
//  ^^^^^^ return a boolean
}).then(function(okCheck) {
//               ^^^^^^^ receive it here as a parameter
    … // do some additional stuff using it
});

答案 1 :(得分:0)

两点:

  • okCheck无法在User.findOne的回调或链接的.then的回调的上下文之外可靠地使用,因此将它作为外部变量没有任何好处,事实上这样做是不好的做法。 / LI>
  • 您不应该尝试同时使用直接回调链式then() - 它们是替代品。

假设这是Mongoose,并且userInfo.checked.indexOf()是同步的,您可以编写以下任一项:

将回调传递给User.findOne()

User.findOne({publicID: id}, function(err, userInfo) {
    if(err) {
        console.log(err);
    } else {
        if (userInfo.checked.indexOf(id) > -1) {
            // do additional stuff
        } else {
            // do other stuff
        }
    }
});

链接.then()User.findOne().exec()

返回的承诺
User.findOne({publicID: id}}).exec().then(function(userInfo) {
    if(userInfo.checked.indexOf(id) > -1) {
        // do additional stuff
    } else {
        // do other stuff
    }
}, function(err) {
    console.log(err);
});

注意:即使它不是Mongoose,大部分仍然适用。

答案 2 :(得分:-1)

这不是它的工作原理,你必须返回承诺才能使用" .then()"。

var okCheck = false;

User.findOne({publicID: id}).exec()
.then(function (userInfo) {
    if ( userInfo.checked.indexOf(id) > -1 ){
      okCheck = true;
    }
    return okCheck
})
.then(function (okCheck) {
  //do some additional stuff using the boolean okCheck
})

这里" .exec()"回报承诺。