在循环中使用 q promise 的最佳方法是什么?等待链完成,然后再迭代到下一个
Whats the best approach to use q promise in a loop? Waiting for chain to complete before iterating to next
我有以下情况:
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')
})
}
我想等待链完成,然后再迭代到下一个。解决这个问题的最佳方法是什么?
在这些例子中,我使用标准Promise
s。如果您需要使用(很棒的)Q 库,您可以通过在Promise.resolve(arg).then(fn)
位置替换Q.fcall(fn, arg)
或使用Q()
而不是Promise.resolve()
来缩短它。
通过链接承诺
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);
}
使用 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');
});
感谢 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)
相关文章:
- 等待300毫秒,然后使用jQuery向下滑动菜单
- 等待函数完成,然后将返回值分配给变量JS
- 等待 MongoDB findOne 回调完成,然后再完成 app.get()
- 流星技术/模式,用于等待数据库变量更改,然后在 in 之后执行某些操作
- jQuery-等待此元素,然后执行1次
- 如何正确地等待元素获得正确的宽度,然后在Angular 2中访问它
- JavaScript:从javascript加载图像,然后等待该图像的“load”事件
- 等待 AJAX,然后再继续执行单独的函数
- 使用生成器等待输入,然后再继续 forEach 循环的主体
- 等待多个 ipc 调用完成,然后再继续电子/冗余
- 等待Javascript网页抓取功能完成,然后再运行下一页
- 等待 busboy on #file 完成,然后再调用 on#finish
- 预加载等待 3 秒钟,然后再打开页面
- 等待几秒钟,然后再运行下一步量角器
- 如何等待findOneAndUpdate完成,然后再继续async.series
- 等待 API 调用在 Javascript 中完成,然后再继续
- Jquery 淡出 - 等待完成 - 然后删除
- 请等待异步操作 (firebase) 调用完成,然后再加载网页
- 等待多个条件,然后执行函数
- 运行 PHP,等待;运行 JavaScript,等待;然后提交表格