如何打破承诺内的循环?

我正在做一个使用蓝鸟库的QA(问题/答案)应用程序。 所以这里的情况是:

  1. 用户用一些问题的答案填写表格(例如5个问题)。
  2. 一个问题有超过1个可能的答案:“问题有很多答案”
  3. 答案在数据库上使用node.bcryptencryption(bcrypt)
  4. 循环播放答案时,如果用户答案匹配,则不需要继续检查该问题的答案。

所以在做同步的时候,解决这个问题是一个普遍的问题,但是我有点失落,要做与承诺的asynchronous。

以下是我不知道如何进行的一个示例:

.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 // }) }) 

假设你想按顺序调用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); }); }) 

它将“recursion地”通过answers数组,停止第一个true结果。 要返回正确的答案(而不是true的“find”)或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); }); 

或更好的更详细

 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); 

下面的解决scheme(未经testing)实现一个状态机模拟foreach循环。 当匹配被发现或者当没有更多的比较答案时, 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 });