javascript - How to break loop inside a promise? - Stack Overflow

I'm doing kind of QA (QuestionAnswers) application using the Bluebird library. So here's the

I'm doing kind of QA (Question/Answers) application using the Bluebird library. So here's the scenario:

  1. User fill the form with answers for some number of questions (e.g 5 questions).
  2. A question has more than 1 possible answer: "Question has many answers"
  3. Answers are encrypted (bcrypt) on database using node.bcrypt
  4. When looping through answers, if user answer matches, there's no need to continue checking the answer for that question.

So it's a mon problem to solve when doing things synchronous, but I'm a little lost to do that async with promises.

Here's a sample of what I don't know how to proceed:

  .then(function(answers) {
    var pare = Promise.promisify(bcryptpare);
    // foreach answer, I need to check like this
    // pare(answer.password, user.password).then(function(match){
    //      if (match) break; <-- something like this
    //   })
  })

I'm doing kind of QA (Question/Answers) application using the Bluebird library. So here's the scenario:

  1. User fill the form with answers for some number of questions (e.g 5 questions).
  2. A question has more than 1 possible answer: "Question has many answers"
  3. Answers are encrypted (bcrypt) on database using node.bcrypt
  4. When looping through answers, if user answer matches, there's no need to continue checking the answer for that question.

So it's a mon problem to solve when doing things synchronous, but I'm a little lost to do that async with promises.

Here's a sample of what I don't know how to proceed:

  .then(function(answers) {
    var pare = Promise.promisify(bcrypt.pare);
    // foreach answer, I need to check like this
    // pare(answer.password, user.password).then(function(match){
    //      if (match) break; <-- something like this
    //   })
  })
Share Improve this question edited Mar 28, 2014 at 1:03 Benjamin Gruenbaum 277k89 gold badges521 silver badges517 bronze badges asked Feb 13, 2014 at 14:53 rizidororizidoro 13.4k18 gold badges60 silver badges86 bronze badges 3
  • You may have to get the encrypted answer separately before the loop, and inside the callback start the loop and just do basic checking (if hash == password) break; – tymeJV Commented Feb 13, 2014 at 14:59
  • @tymeJV I think I can't do that, cause when I hash the password with bcrypt, a different value is generated from the database previously generated value... that's the reason why I need the bcrypt pare function... Maybe I'm wrong... – rizidoro Commented Feb 13, 2014 at 15:06
  • Don't have my bcrypt repo up in front of me but that sounds right - callback hell :\ - this post might help: stackoverflow./questions/13214862/… – tymeJV Commented Feb 13, 2014 at 15:11
Add a ment  | 

3 Answers 3

Reset to default 3

Assuming you want to call the pares sequentially, this will do it:

.then(function(answers) {
    var pare = Promise.promisify(bcrypt.pare),
        i = 0;
    return Q(false).then(function checkNext(res) {
        return res ||
               i<answers.length && pare(answers[i++].password, user.password)
                                     .then(checkNext);
    });
})

It will "recursively" step trough the answers array, stopping on the first true result. To return the correct answer (instead of just true for "found") or null (if not found) like @Noseratio's code, you could use

    var i = 0, answer;
    return Q(false).then(function checkNext(res) {
        return res ? answer : (i<answers.length || null) && pare((answer = answers[i++]).password, user.password).then(checkNext);
    });

or better the more verbose

function next(i) {
    if (i < answers.length)
        return pare(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. The result promise is resolved when the match has been found, or when there is no more answers to pare:

  .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 (pare(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
  pare(answer.password, user.password)
    .then(match => {
      if (match) breakLoop = true
    })
    .catch(err => breakLoop = true)
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745325503a4622637.html

相关推荐

  • javascript - How to break loop inside a promise? - Stack Overflow

    I'm doing kind of QA (QuestionAnswers) application using the Bluebird library. So here's the

    14小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信