方法一:for 循环 + await
简单的 for 循环是依次进行循环的,不像 Array.forEach,Array.map 方法是并发执行的,利用这一特点加 async / await 实现:
(async () => {
const sleep = delay => {
return new Promise((resolve, reject) => {
setTimeout(_ => resolve(), delay)
})
}
const task = (i) => {
return new Promise(async (resolve, reject) => {
await sleep(500)
console.log(`now is ${i}`)
++i
resolve(i)
})
}
let param = 0
for (let i = 0; i < 4; i++) {
param = await task(param)
}
})()
//输出:
//now is 0
//now is 1
//now is 2
//now is 3
方法二:Array.prototype.reduce
reduce有初始值,积累值,以及当前值的概念。其中 积累值可以看作是前一个值,通过返回积累值又可以看作是 下一个值。使用reduce来解决:
const sleep = delay => {
return new Promise((resolve, reject) => {
setTimeout(_ => resolve(), delay)
})
}
const task = (i) => {
return new Promise(async (resolve, reject) => {
await sleep(500)
console.log(`now is ${i}`)
++i
resolve(i)
})
}
[task, task, task, task].reduce(async (prev, task) => {
const res = await prev
return task(res)
}, 0)
//输出:
//now is 0
//now is 1
//now is 2
//now is 3
可以理解为:
prev:前一个 异步任务(promise)
task:当前的异步任务
当前的异步任务需要上一个异步任务的结果作参数,所以很显然要 await prev。