[英]Sequential iteration using ES6 promises
我期望在node.js下面的代码将按以下顺序打印输出
1000
2000
3000
4000
"All tasks completed"
而是按以下提到的顺序打印
"All tasks completed"
1000
2000
3000
4000
编码
'use strict';
var tasks = [1000, 2000, 3000, 4000];
var promise = Promise.resolve();
function test() {
tasks.forEach(function(task) {
promise = promise.then(function() {
setTimeout(function() {
console.log(task);
}, task);
});
});
}
test();
promise.then(function() {
console.log('All tasks completed');
});
需要修改什么,以便最后打印“所有任务已完成”。
在所有then
函数中,您什么都不返回,而是触发异步操作。 因此,promise链与异步操作无关。 这就是为什么您无法按需要控制流量的原因。
您可能要做的是,从每个then
处理程序中返回一个Promise,仅当异步操作完成时才解决此问题,如下所示
tasks.forEach(function(task) {
promise = promise.then(function() {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log(task);
resolve();
}, task);
})
});
});
请记住, 这将一次触发异步操作 。 例如,一秒钟后,它将打印1000,第二个异步操作将开始,它将等待两秒钟,然后打印2000,依此类推。 基本上,您的程序将在大约10秒钟(1 + 2 + 3 + 4秒)后退出,因为我们将依次执行所有异步功能。
但是, 如果您希望所有人都立即触发 ,请使用Promise.all
,就像这样
'use strict';
var tasks = [1000, 2000, 3000, 4000];
function test() {
return Promise.all(tasks.map(function(task) {
return new Promise((resolve, reject) => {
setTimeout(function() {
console.log(task);
resolve();
}, task);
})
}));
}
test().then(function() {
console.log('All tasks completed');
});
现在,所有异步功能都立即被触发,因此一秒钟后,将打印1000,两秒钟后将打印2000,依此类推。 您的程序将在4秒钟后完成所有异步操作,因为所有异步操作都会立即启动。
目前,这是我发现的唯一一种以顺序AND阻塞方式迭代promise数组的方法...
请检查代码示例...
const list = [1,2,3,4,5];
数字越高,兑现承诺的速度越快
const functionWithPromise = item => {
return new Promise((resolve) =>{
setTimeout(resolve, 6000 - (1000 * item ) , item);
})}
Promise.all返回带有promise的数组
const getData = async () => Promise.all(await iterateSequentiallyPromiseArray(list,functionWithPromise));
for循环是唯一以阻塞方式迭代的循环
const iterateSequentiallyPromiseArray = async (array, fn) => {
try {
const results = [];
for (let i = 0; i < array.length; i++) {
console.log('Start with index: ', i);
const r = await fn(array[i]);
console.log('in promise iteration', r);
results.push(r);
}
return results; // will be resolved value of promise
} catch (err) {
console.log('_processArray');
throw err;
}
};
开始连锁
getData().then(console.log);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.