68

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

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

错误信息是:

await 是保留字

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

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

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

6 回答 6

152

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

明智的做法是将函数传递给map异步。这意味着这map将返回一系列承诺。然后,我们可以Promise.all在所有的 Promise 返回时使用它来获取结果。由于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);
}
于 2017-02-27T23:01:59.427 回答
44

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

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

这个怎么运作:

  • inputArray.map(async ...)返回一个 promises 数组 - 每个值对应一个inputArray.
  • 放置Promise.all()一系列承诺将其转换为单个承诺。
  • 单个promise fromPromise.all()返回一个值数组——每个promise 都解析为一个值。
  • 我们放在await前面,Promise.all()以便等待组合的 Promise 解析并将已解析的子 Promise 数组存储到变量resultArray中。

最后,我们通过函数映射resultArray为每一项 in获得一个输出值。在结果可用之前,我们必须等待所有异步函数解决。inputArraysomeAsyncFunction

于 2019-10-08T04:56:48.103 回答
13

那是因为函数 inmap不是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)
        }
    });
};

在 Babel REPL 中尝试一下

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

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

于 2017-02-27T15:57:46.630 回答
3

这将是 2 条指令,但只需使用额外的指令转移“等待”

let results = array.map((e) => fetch('....'))
results  = await Promise.all(results)
于 2021-07-07T04:21:28.613 回答
1

我尝试了所有这些答案,但没有一个适合我的情况,因为所有答案都返回一个promise不是result of the promise这样的对象:

{
  [[Prototype]]: Promise
  [[PromiseState]]: "fulfilled"
  [[PromiseResult]]: Array(3)
  0: ...an object data here...
  1: ...an object data here...
  2: ...an object data here...
  length: 3
  [[Prototype]]: Array(0)
}

然后我找到了这个答案https://stackoverflow.com/a/64978715/8339172说明map函数是否异步或承诺感知。所以我没有使用await内部map函数,而是使用for循环和await单个项目,因为他说for循环是有async意识的并且会暂停循环。

于 2021-09-27T06:08:04.557 回答
0

如果您希望在继续下一个之前解决每个重新映射的值,您可以将数组作为异步迭代处理。

下面,我们使用库iter-ops将每个值重新映射为 promise,然后生成一个具有解析值的对象,因为map它本身不应该在内部处理任何 promise。

import {pipe, map, wait, toAsync} from 'iter-ops';

const i = pipe(
    toAsync(myArray), // make asynchronous
    map(myValue => {
        return service.getByValue(myValue).then(a => ({id: 'my_id', myValue: a}))
    }),
    wait() // wait for each promise
);

(async function() {
    for await (const a of i) {
        console.log(a); // print resulting objects
    }
})

在每个值之后,我们使用wait在生成每个重新映射的值时对其进行解析,以保持解析要求与原始问题一致。

于 2021-12-25T21:16:40.583 回答