那么承诺就行不通了
then Promise doesn't work
我有一个数据库统计报告的代码。
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) {
for (index in quizes) {
if (quizes[index].Comment.length) {
statistics.commented_questions++;
} else {statistics.no_commented++;}
};
})
})
})
.catch(function(error) {next(error)})
.finally(function() {next()});
};
它工作正常,直到SQL语句,但从不做循环for,所以我永远不能得到
statistics.commented_questions
或
statistics.no_commented
提前感谢!
当将承诺链接在一起时,它们需要知道前一个承诺何时被拒绝或履行。在你当前的代码中,初始的promise从来不返回一个值/promise,而是调用一个async函数。对于JS引擎来说,代码基本上是这样的:
exports.calculate = function(req, res, next) {
models.Quiz.count()
.then(function(questions) {
statistics.questions = questions;
// ASYNC FUNCS THAT ARE NEVER RETURNED
// ...
// functions in JS without an explicit return statement return nothing (essentially `undefined`)
})
.catch(function(error) {
next(error)
})
.finally(function() {
next()
});
};
因此,在引擎等待初始承诺被完成/拒绝之后,它会为一个异步操作触发另一个承诺,该操作返回一个承诺,但不会将其返回到原始承诺链。默认情况下,原始承诺链接收undefined
,然后将其传递给链中的下一个方法。在本例中,它将是finally
方法。
你可能想知道为什么第二个承诺还在更新信息,如果它没有等待它。这是一个竞态条件,从本质上讲,promise是获胜的。
要正确地将承诺链接在一起,您需要将新承诺返回到旧承诺链中,如下所示:
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) {
for (index in quizes) {
if (quizes[index].Comment.length) {
statistics.commented_questions++;
} else {
statistics.no_commented++;
}
}
}).catch(next).finally(next);
};
如果你使用的是支持本地Promise
对象的Node/IO版本,你可以利用这一点来发出并发请求,因为它们都不依赖于彼此。注意:Promise
API没有finally()
方法,但我们可以使用then()
的第二个参数来传递错误。
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` is an array of [questions, comments, quizes]
statistics.questions = results[0];
statistics.comments = results[1];
statistics.average_comments = (statistics.comments / statistics.questions).toFixed(2);
for (index in results[2]) {
if (results[2][index].Comment.length) {
statistics.commented_questions++;
} else {
statistics.no_commented++;
}
}
}).then(next, next);
};
相关文章:
- 我的职位回报太快了,如何做出承诺
- 打破承诺链的好方法是什么
- 从函数返回角度承诺
- 我怎样才能获得承诺的价值
- 延期承诺值未更新/解析/延期
- 在承诺链中处理早期回报的最佳方式
- 承诺在非节点式回调上使用Bluebird
- 简单的ES6承诺问题-交换解决和拒绝参数
- 组合承诺和非承诺值
- 带有对象/原型的链式承诺(Q延期)
- AngularJS$q承诺使用socket.io
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- 当一些承诺失败时,如何继续使用$q.all()
- Nodejs和express路由,如何处理客户端的承诺
- 如何在多承诺链中处理谷歌地图API V3事件
- 承诺合并流
- JavaScript承诺-无法读取属性'那么'的未定义
- 在$http内解决/拒绝承诺是行不通的
- 用承诺来敷衍是行不通的
- 那么承诺就行不通了