javascript - then Promise doesn't work -
i have code statistic report on db.
exports.calculate = function(req, res, next) { models.quiz.count() .then(function(questions) { statistics.questions = questions; models.comment.count().then(function(comments) { statistics.comments = comments; statistics.average_comments = (statistics.comments / statistics.questions).tofixed(2); models.quiz.findall({ include: [{model: models.comment}]}) .then(function(quizes) { (index in quizes) { if (quizes[index].comment.length) { statistics.commented_questions++; } else {statistics.no_commented++;} }; }) }) }) .catch(function(error) {next(error)}) .finally(function() {next()}); };
it works until sql statement, never makes loop for, never can
statistics.commented_questions
or
statistics.no_commented
thank's in advanced!
when chaining promises need know when previous promise either rejected or fulfilled. in current code, initial promise never returns value/promise instead calls async function. code looks js engine:
exports.calculate = function(req, res, next) { models.quiz.count() .then(function(questions) { statistics.questions = questions; // async funcs never returned // ... // functions in js without explicit return statement return nothing (essentially `undefined`) }) .catch(function(error) { next(error) }) .finally(function() { next() }); };
so, after engine waits initial promise fulfilled/rejected fires off promise async operation returns promise doesn't return original promise chain. default original promise chain receives undefined
passed on next method in chain. in case finally
method.
you might wonder why second promise still updating information if it's not waiting it. race condition , promise winning.
to chain promises need return new promise old promise chain so:
exports.calculate = function(req, res, next) { models.quiz.count().then(function(questions) { statistics.questions = questions; return models.comment.count(); }).then(function(comments) { statistics.comments = comments; statistics.average_comments = (statistics.comments / statistics.questions).tofixed(2); return models.quiz.findall({ include: [{ model: models.comment }] }); }).then(function(quizes) { (index in quizes) { if (quizes[index].comment.length) { statistics.commented_questions++; } else { statistics.no_commented++; } } }).catch(next).finally(next); };
if using version of node/io has support native promise
object can leverage bit issue concurrent requests since none of them dependent on each other. note: promise
api not have finally()
method can use second argument then()
pass error along.
exports.calculate = function(req, res, next) { promise.all([ models.quiz.count(), models.comment.count(), models.quiz.findall({ include: [{ model: models.comment }] }) ]).then(function(results) // `results` array of [questions, comments, quizes] statistics.questions = results[0]; statistics.comments = results[1]; statistics.average_comments = (statistics.comments / statistics.questions).tofixed(2); (index in results[2]) { if (results[2][index].comment.length) { statistics.commented_questions++; } else { statistics.no_commented++; } } }).then(next, next); };
Comments
Post a Comment