异步/等待在数组函数reduce中的应用

3

我有两个代码片段(并行和串行),用reduce在数组上执行一个简单的异步函数。我不明白为什么执行要等到调用Promise.all才开始。这是最好的方法吗?

// Function returning promise with root value
async function proot(x) {
    return new Promise((res,rej)=>{ 
        setTimeout( () => { 
            console.log(x*x);
            res(x*x) 
        },1000)    
    })
}

// Parallel Execution
var arr1 = [2,3,4].reduce((prev,next)=>{
    return prev.concat(proot(next))
},[])
arr1 = await Promise.all(arr1)

// Sequential Execution
var arr2 = [2,3,4].reduce( async (prev,next)=>{
    return (await prev).concat(await proot(next))
},Promise.resolve([]))
arr2 = await Promise.all([arr2])

只是想补充一下,当我不使用调试时,第二个连续执行将在不调用Promise.all()的情况下工作。也许这与我的IDE和mocha有关,而不是JavaScript。 - ucipass
1个回答

2

当您调用返回Promise的函数时,Promise内部的代码将被执行:

// Parallel Execution
var arr1 = [2,3,4].reduce((prev,next)=>{
    return prev.concat(proot(next))
},[])

但是它返回的是一个承诺(promise),而不是一个值。你需要处理这个承诺,以获取它解决的值。

在你的情况下,你不需要使用reduce。Map也可以起作用:

var arr = [2,3,4].map((n) => proot(n));
Promise.all(arr).then((values) => {})

或者:

var arr = [2,3,4].map(async (n) => await proot(n));

1
Alberto,我将会标记你的回答为正确,因为这解决了我的问题。实际上,我需要在reduce内部使用concat,因为我可能需要在数组的单个成员位置插入多个数组元素。与此同时,我已经意识到,在我调试setTimeout函数时,它不会被触发,这就是为什么在我调用Promise.all之前我没有在屏幕上看到结果的原因。所以事实上,我不需要调用promise.all来获取结果。 - ucipass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接