我在这段代码中得到了编译时错误:
const someFunction = async (myArray) => { return myArray.map(myValue => { return { id: "my_id", myValue: await service.getByValue(myValue); } }); };
错误信息是:
“等待”是一个保留字
为什么我不能这样使用它?
这是因为 map中的函数不是 异步,所以不能在它的 return 语句中使用 等待。它通过以下修改进行编译:
map
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
您不能像您想象的那样执行此操作,因为如果 await不直接位于 async函数中,则无法使用它。
await
async
这里明智的做法是将函数异步传递给 map。这意味着 map将返回一个承诺数组。然后,当所有的承诺返回时,我们可以使用 Promise.all来获得结果。因为 Promise.all本身返回一个承诺,所以外部函数不需要是 async。
Promise.all
const someFunction = (myArray) => { const promises = myArray.map(async (myValue) => { return { id: "my_id", myValue: await service.getByValue(myValue) } }); return Promise.all(promises); }
如果要使用异步映射函数运行 map,可以使用以下代码:
const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i)));
工作原理:
inputArray.map(async ...)
inputArray
Promise.all()
resultArray
最后,我们在 resultArray中为 inputArray中的每个项目得到一个输出值,通过函数 someAsyncFunction进行映射。我们必须等待所有异步函数解析后才能得到结果。
someAsyncFunction
它将是2个指令,但只是移动“等待”与额外的指令
let results = array.map((e) => fetch('....')) results = await Promise.all(results)
我尝试了所有这些答案,但是没有一个适合我的情况,因为所有的答案都返回一个 promise对象,而不是像这样返回一个 result of the promise对象:
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函数是否不是异步的或者承诺感知的。 因此,我没有在 map函数中使用 await,而是使用 for循环和 await单独的项目,因为他说 for循环是 async感知的,会暂停循环。
for
如果希望在转移到下一个值之前解析每个重新映射的值,可以将数组作为异步迭代进行处理。
下面,我们使用库 ITER-OPS,将每个值重新映射到承诺,然后生成一个具有解析值的对象,因为 map本身不应该在内部处理任何承诺。
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 } })
在每个值之后,我们使用 等等在生成每个重新映射的值时解析它们,以保持解析要求与原始问题一致。