我几乎肯定对此有一个解释,但我只是花了一个多小时试图弄清楚为什么我的异步代码在尝试使用 ary.filter 转换数组时似乎提前解决了()
,但是当使用 ary.map()
时,异步会在我期望的时候解析。任何可以帮助阐明这个主题的人将不胜感激!
为了清楚起见,我还使用 Node 8.2.1。
因此,为了提供一些代码和输出来描述该问题,这里是一个使用 ary.map
的示例,它有效并在控制台中提供以下输出。
(async () => {
const timeStart = Date.now()
const ary = new Array(20).fill(0).map((v, i) => i+1)
const newAry = await Promise.all(
ary.map(async val => {
return await new Promise((resolve, reject) => {
setTimeout(() => resolve(val*2), 1000)
})
})
)
console.log('original ary', ary)
console.log('newAry is', newAry)
const timeEnd = Date.now()
console.log(timeEnd - timeStart, 'milliseconds between start and end')
})()
控制台输出如下:
original ary [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
newAry is [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ]
1022 milliseconds between start and end
正如您所期望的,原始数组转换后大约有 1 秒的时间,输出与预期一致。
以下代码非常相似,但使用 ary.filter()
并且未按预期返回。
(async () => {
const timeStart = Date.now()
const ary = new Array(20).fill(0).map((v, i) => i+1)
const newAry = await Promise.all(
ary.filter(async val => {
return await new Promise((resolve, reject) => {
setTimeout(() => resolve(Math.random() < 0.5), 1000)
})
})
)
console.log('original ary', ary)
console.log('newAry is', newAry)
const timeEnd = Date.now()
console.log(timeEnd - timeStart, 'milliseconds between start and end')
})()
输出如下:
original ary [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
newAry is [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
18 milliseconds between start and end
为什么在使用 async/时,ary.filter()
在转换数组并在适当的时间解析方面与 ary.map()
的行为不同等待?
最佳答案
调用 Promise.all()
仅对 Promise 数组有意义。
.map()
返回其回调的结果,如果回调是异步的,则该结果是一个 promise 。因此,效果很好。
.filter()
将其回调结果视为 bool 值(事实并非如此),然后返回原始数组中的项目。
关于javascript - async/await : asynchronous array transformation using Array.prototype.map(有效)与Array.prototype.filter(无效),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45492975/