我有以下情况:
var ids = [120, 121, 122, 123, 124]
function dummyPromise(pause) {
var deferred = Q.defer();
setTimeout(function() {
console.log(pause);
deferred.resolve(pause);
}, pause);
return deferred.promise;
}
for(var i = 0; i < ids.length; i++) {
dummyPromise(ids[i])
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.done(function(){
console.log('done')
})
}
我想在迭代到下一个之前等待链完成。什么是解决这个问题的最好方法?
答案 0 :(得分:1)
在这些示例中,我使用标准Promise
。如果您需要使用(令人敬畏的)Q库,可以通过在Q.fcall(fn, arg)
的地方替换Promise.resolve(arg).then(fn)
或使用Q()
代替Promise.resolve()
来缩短Q库。
var q = Promise.resolve();
for (var i = 0; i < 10; i++) {
(function(item, index){
q = q.then(function() {
return // do async stuff here
});
})(ids[i], i);
}
q.then(function() {
// all iterations finished
});
function forEachAsync(arr, fn) {
var index = 0;
function next() {
if (index < arr.length) {
var current = index++;
return Promise.resolve().then(function() {
return fn(arr[current], current, arr);
}).then(next);
}
}
return Promise.resolve().then(next);
}
...
forEachAsync(ids, function(item, idx) { ... }).then(...)
function forOfAsync(iterable, fn) {
var iterator = iterable[Symbol.iterator]();
function next() {
var iteration = iterator.next();
if (iteration.done) {
return iteration.value;
} else {
return Promise.resolve(iteration.value).then(fn).then(next);
}
}
return Promise.resolve().then(next);
}
forOfAsync(ids, function(id) { ... }).then(...)
async-await
for (let id of ids) {
await doSomeAsyncStuffWithId(id);
}
答案 1 :(得分:0)
使用array#reduce - 您的代码看起来像
ids.reduce(function(prev, id) {
return prev
.then(function() {
return dummyPromise(id)
})
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.then(function(){ // if you do done you can't chain
console.log('done')
});
}, Q(null))
.done(function() { // done here though
console.log('all done');
});
答案 2 :(得分:0)
感谢https://github.com/jprichardson/node-batchflow。我最后使用了这种方法:请参阅小提琴:https://jsfiddle.net/c9fxqhs5/
var ids = [120, 121, 122, 123, 124]
function dummyPromise(pause) {
var deferred = Q.defer();
setTimeout(function() {
console.log(pause);
deferred.resolve(pause);
}, pause);
return deferred.promise;
}
function again(i) {
if (i < ids.length) {
$('body').append('<p>processing: ' + i + '</p>');
dummyPromise(ids[i])
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.then(dummyPromise)
.done(function(result){
$('body').append('<p>done: ' + i + ' result=' + result + '</p>');
again(i+1)
})
} else {
console.log('All Done.')
}
}
again(0)