gpt4 book ai didi

javascript - Promise.all 对遍历生成器无效

转载 作者:行者123 更新时间:2023-11-30 15:58:15 27 4
gpt4 key购买 nike

为了理解 Javascript 生成器和 promises,我检查过它们是很好的盟友。我需要遍历 promise 协程(Promise.coroutine 来自 Bluebird 库)使得以正确的顺序执行一些 promise 变得容易。使用此代码(对于延迟的反模式感到抱歉,我稍后会学会避免它):

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 导致一些 promise 在其他 promise 之前结束。

如果我在 promise 中包含 if(i == 3) deferred.reject(new Error(' ERROR!!')); ,则仅针对该 promise 而不是针对其他的,它在其他的 promise 之后被抛出:

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 must be a function

如果我这样做:

var coroutine = function* coroutine(i) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
};

相同的 generatorFunction must be a function 仍然存在。

您知道这里有什么问题吗,或者是否有比 Promise.all 更好的“迭代”方法?

最佳答案

sorry for the deferred anti-pattern

实际上你没有使用the deferred antipatternmyPromise 中,使用 deferreds 从像 setTimeout 这样的接受回调的异步函数中获得 promise 是完全没问题的。您可以改用Promise 构造函数,但这并不是绝对必要的。最好的解决方案当然是 Promise.delay (Bluebird) 或 Q.delay (Q) :-)

my for loop seems to be not good because some promises are ending before the others

那是因为您对协程(执行异步操作)的调用在循环内。如果您将循环放在生成器函数中,它将按预期工作:

router.get('/', function(req, res, next) {
Promise.coroutine(function*() {
for (var i = 0; i < 5; i++) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
console.log('Then');
}
})()
.catch((err) => next(err));
});

甚至更好:

var run = Promise.coroutine(function*(req, res, next) {
for (var i = 0; i < 5; i++) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
console.log('Then');
}
});
router.get('/', function(req, res, next) {
run(req, res, next).catch(next);
});

关于javascript - Promise.all 对遍历生成器无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38169270/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com