【发布时间】:2016-11-05 06:34:45
【问题描述】:
试图了解 Javascript 生成器和 Promise,我已经检查过它们是很好的盟友。我需要遍历承诺的协程(来自 Bluebird 库的Promise.coroutine)可以轻松地以正确的顺序执行一些承诺。使用这段代码(对不起,延迟的反模式,我稍后会学会避免它):
function myPromise(x,time,i){
var deferred = Q.defer();
setTimeout(() => {
deferred.resolve(x + i);
},time);
return deferred.promise;
}
router.get('/', function(req, res, next) {
for (var i = 0; i < 5; i++) {
Promise.coroutine(function*(i) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
})(i)
.then(() => {
console.log('Then');
}).
catch((err) => next(err));
}
});
控制台的输出(几乎)正确:
a0 b0
a1 b1
a2 b2
Then
Then
Then
a3 b3
a4 b4
Then
Then
检查一下,我的 for 循环似乎不太好,因为由于 Then,一些承诺在其他承诺之前结束。
如果我在承诺中包含if(i == 3) deferred.reject(new Error(' ERROR!!'));,则仅针对该承诺而不是其他承诺引发错误,并且在其他承诺之后引发错误:
ERROR!!
a0 b0
Then
a1 b1
a2 b2
Then
Then
a4 b4
Then
我认为使用 for 循环进行迭代永远不会成为此类问题的解决方案。进行了更多研究,我尝试使用Promise.all 对Promise.coroutine 进行一系列调用:
Promise
.all([
Promise.coroutine(1),
Promise.coroutine(2),
Promise.coroutine(3)
])
.then(() => {
console.log('then');
})
.catch((err) => next(err));
但在这种情况下,我认为错误:
generatorFunction 必须是函数
如果我这样做:
var coroutine = function* coroutine(i) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
};
同样的generatorFunction 必须是函数。
您知道这里出了什么问题,或者是否有比Promise.all 更好的“迭代”方式?
【问题讨论】:
标签: javascript node.js promise generator bluebird