I'm doing kind of QA (Question/Answers) application using the Bluebird library. So here's the scenario:
- User fill the form with answers for some number of questions (e.g 5 questions).
- A question has more than 1 possible answer: "Question has many answers"
- Answers are encrypted (bcrypt) on database using node.bcrypt
- 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:
- User fill the form with answers for some number of questions (e.g 5 questions).
- A question has more than 1 possible answer: "Question has many answers"
- Answers are encrypted (bcrypt) on database using node.bcrypt
- 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
3 Answers
Reset to default 3Assuming you want to call the pare
s 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
评论列表(0条)