我原以为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');
});
需要修改什么以便"所有任务完成"将在最后打印。
答案 0 :(得分:4)
在所有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秒后完成所有异步操作,因为所有异步操作都会立即启动。
答案 1 :(得分:0)
当前,这是我发现的唯一一种以顺序AND阻塞方式遍历promise数组的方法...
请检查代码示例...
const list = [1,2,3,4,5];
数字越大,承诺兑现的速度越快
const functionWithPromise = item => {
return new Promise((resolve) =>{
setTimeout(resolve, 6000 - (1000 * item ) , item);
})}
Promise.all返回一个带有promises的数组
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);