[英]How to break loop inside a promise?
I'm doing kind of QA (Question/Answers) application using the Bluebird library. 我正在使用Bluebird库做一些QA(问题/答案)应用程序。 So here's the scenario: 所以这是场景:
So it's a common problem to solve when doing things synchronous, but I'm a little lost to do that async with promises. 所以当做同步事情时,这是一个常见的问题需要解决,但我有点迷失与promises异步。
Here's a sample of what I don't know how to proceed: 以下是我不知道如何处理的示例:
.then(function(answers) {
var compare = Promise.promisify(bcrypt.compare);
// foreach answer, I need to check like this
// compare(answer.password, user.password).then(function(match){
// if (match) break; <-- something like this
// })
})
Assuming you want to call the compare
s sequentially, this will do it: 假设您compare
顺序调用compare
,这将执行此操作:
.then(function(answers) {
var compare = Promise.promisify(bcrypt.compare),
i = 0;
return Q(false).then(function checkNext(res) {
return res ||
i<answers.length && compare(answers[i++].password, user.password)
.then(checkNext);
});
})
It will "recursively" step trough the answers
array, stopping on the first true
result. 它将“递归地”逐步通过answers
数组,停止第一个true
结果。 To return the correct answer (instead of just true
for "found") or null
(if not found) like @Noseratio's code, you could use 要返回正确的答案(而不仅仅是“找到”为true
)或null
(如果没有找到),如@Noseratio的代码,你可以使用
var i = 0, answer;
return Q(false).then(function checkNext(res) {
return res ? answer : (i<answers.length || null) && compare((answer = answers[i++]).password, user.password).then(checkNext);
});
or better the more verbose 或者更好,更详细
function next(i) {
if (i < answers.length)
return compare(answers[i].password, user.password).then(function(res) {
return res ? answers[i] : next(i+1);
});
else
return null;
}
return next(0);
The following solution (untested) implements a state machine to simulate foreach
loop. 以下解决方案(未经测试)实现状态机以模拟foreach
循环。 The result
promise is resolved when the match has been found, or when there is no more answers to compare: 找到匹配项后,或者没有更多答案要比较时, result
承诺会得到解决:
.then(function(answers) {
var result = new Promise();
var i = 0;
function nextStep() {
if (i >= answer.length)
result.resolve(null);
else {
var answer = answers[i];
if (compare(answer.password, user.password).then(function(match) {
if (match)
result.resolve(answer);
else {
i++;
nextStep(); // do the next step
}
})
}
}
process.nextTick(nextStep); // do the first step asynchronously
return result; // return the result as a promise
});
It could be a simple solution: 这可能是一个简单的解决方案:
let breakLoop = false
for (let answer of arr) {
if (breakLoop) continue
compare(answer.password, user.password)
.then(match => {
if (match) breakLoop = true
})
.catch(err => breakLoop = true)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.