Javascript JS-然后等待承诺
我知道这是一个常见的话题,但我只想确认我对JS和承诺的理解 下面的代码段失败了,因为Javascript JS-然后等待承诺,javascript,promise,Javascript,Promise,我知道这是一个常见的话题,但我只想确认我对JS和承诺的理解 下面的代码段失败了,因为then块实际上没有等待上面的代码段完成。也就是说,我没有得到okCheck的最终/正确值 var okCheck = false; User.findOne({publicID: id}, function (err, userInfo) { if ( userInfo.checked.indexOf(id) > -1 ){ okCheck = true; } }
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
}
所以要解决这个问题——据我所知,我需要使用一个返回值
——这是正确的吗
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的最终值
谢谢。这不是它的工作原理,您必须返回承诺才能使用“.then()” 此处“.exec()”返回承诺 据我所知,我需要使用
返回值
-这是否正确
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
}
对。但是return
ing值不会影响任何与时间相关的内容
关键是,您从然后回调返回的值将是它返回的承诺的解析值,并成为链中下一个回调的参数
您不应该修改异步回调中的外部作用域变量。正确的方法是推迟行动,直到承诺得到解决,而不是“等待”变量值出现:
// 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
});
两点:
okCheck
无法在User.findOne的回调或chained.then的回调的上下文之外可靠地使用,因此将其作为外部变量没有任何好处,事实上这样做是不好的做法
- 您不应该同时尝试使用直接回调和链接的
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
}
}
});
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);
});
将.then()
链接到用户返回的承诺。findOne().exec()
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
}
}
});
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,这一点仍然适用。在处理程序中使用的new Promise()
绝对没有理由。只需在中返回一个值即可。然后()
handler,这将成为当前承诺的解析值。因此,使用我在问题中的上述代码return-okCheck
本身就可以了?现在其他人对上述内容的看法如何?对我来说有意义??一点吹毛求疵:您不再需要在外部范围内声明okCheck
:它可以在内部范围内声明第一个然后是处理程序。这也迫使您在第二个处理程序中从传递的参数而不是从外部作用域中获取结果。findOne
函数看起来很奇怪:从您的代码来看,它似乎接受回调参数并返回承诺。这两种机制的作用大致相同,您希望函数使用回调或承诺。你确定你叫对了吗?您能否验证您的回调和then
处理程序是否都被调用(例如,通过在它们内部添加console.log()
调用)?这很好-我使用了console.log来检查这一点。我认为下面的答案看起来不错-您认为>从答案来看,这个特殊的findOne
函数是。如果您提到您正在使用的库,那么会更加清楚,这样其他人就不必猜测您的代码正在使用什么函数。;-)User.findOne()
记录在哪里?如果一个方法接受回调并且是可启用的,那么使用其中一个接口就更正常了,而不是同时使用这两个接口。。。。。谢谢@MattiasBuelens,在我提问之前你可能已经回答了我的问题。