Javascript Array#map() 中的异步/等待

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42489918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:11:16  来源:igfitidea点击:

Async/Await inside Array#map()

javascriptasync-awaitecmascript-2017

提问by MyTitle

I'm getting compile time error with this code:

我收到此代码的编译时错误:

const someFunction = async (myArray) => {
    return myArray.map(myValue => {
        return {
            id: "my_id",
            myValue: await service.getByValue(myValue);
        }
    });
};

Error message is:

错误信息是:

await is a reserved word

await 是一个保留字

Why can't I use it like this?

为什么我不能像这样使用它?

I also tried another way, but it gives me same error:

我也尝试了另一种方式,但它给了我同样的错误:

 const someFunction = async (myArray) => {
    return myArray.map(myValue => {
        const myNewValue = await service.getByValue(myValue);
        return {
            id: "my_id",
            myValue: myNewValue 
        }
    });
};

回答by lonesomeday

You can't do this as you imagine, because you can't use awaitif it is not directly inside an asyncfunction.

你不能像你想象的那样做,因为await如果它不是直接在async函数内部,你就不能使用。

The sensible thing to do here would be to make the function passed to mapasynchronous. This means that mapwould return an array of promises. We can then use Promise.allto get the result when all the promises return. As Promise.allitself returns a promise, the outer function does not need to be async.

在这里做的明智的事情是将函数传递给map异步。这意味着map将返回一组承诺。然后我们可以使用Promise.all来获取所有承诺返回时的结果。由于Promise.all本身返回一个承诺,外部函数不需要是async

const someFunction = (myArray) => {
    const promises = myArray.map(async (myValue) => {
        return {
            id: "my_id",
            myValue: await service.getByValue(myValue)
        }
    });
    return Promise.all(promises);
}

回答by helb

That's because the function in mapisn't async, so you can't have awaitin it's return statement. It compiles with this modification:

那是因为 in 函数map不是async,所以你不能在它的 return 语句中使用await。它通过以下修改进行编译:

const someFunction = async (myArray) => {
    return myArray.map(async (myValue) => { // <-- note the `async` on this line
        return {
            id: "my_id",
            myValue: await service.getByValue(myValue)
        }
    });
};

Try it out in Babel REPL

在 Babel REPL 中尝试一下

So… it's not possible to give recommendation without seeing the rest of your app, but depending on what are you trying to do, either make the innerfunction asynchronous or try to come up with some different architecture for this block.

所以……在没有看到应用程序的其余部分的情况下不可能给出推荐,但是根据您要做什么,要么使内部函数异步,要么尝试为这个块提出一些不同的架构。

Update: we might get top-level await one day: https://github.com/MylesBorins/proposal-top-level-await

更新:有一天我们可能会获得顶级等待:https: //github.com/MylesBorins/proposal-top-level-await

回答by MattCochrane

If you want to run map with an asynchronous mapping function you can use the following code:

如果要使用异步映射函数运行 map,可以使用以下代码:

const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i)));

How it works:

这个怎么运作:

  • inputArray.map(async ...)returns an array of promises - one for each value in inputArray.
  • Putting Promise.all()around the array of promises converts it into a single promise.
  • The single promise from Promise.all()returns an array of values - the individual promises each resolve to one value.
  • We put awaitin front of Promise.all()so that we wait for the combined promise to resolve and store the array of resolved sub-promises into the variable resultArray.
  • inputArray.map(async ...)返回一组 Promise - 中的每个值一个inputArray
  • Promise.all()承诺将其转换的阵列周围成一个单一的承诺。
  • 来自单个承诺Promise.all()返回一组值 - 每个承诺都解析为一个值。
  • 我们把await放在前面,Promise.all()以便我们等待组合承诺解析并将已解析的子承诺数组存储到变量中resultArray

In the end we get one output value in resultArrayfor each item in inputArray, mapped through the function someAsyncFunction. We have to wait for all async functions to resolve before the result is available.

最后,我们resultArray为 中的每个项目获得一个输出值,并inputArray通过函数映射someAsyncFunction。在结果可用之前,我们必须等待所有异步函数解析。