Async/Await 里面 Array#map()
Async/Await inside Array#map()
我遇到此代码的编译时错误:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
return {
id: "my_id",
myValue: await service.getByValue(myValue);
}
});
};
错误信息是:
await is a reserved word
为什么我不能这样用?
我也试过另一种方法,但它给了我同样的错误:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
const myNewValue = await service.getByValue(myValue);
return {
id: "my_id",
myValue: myNewValue
}
});
};
那是因为 map
中的函数不是 async,所以你不能在它的 await =28=]语句。它使用此修改进行编译:
const someFunction = async (myArray) => {
return myArray.map(async (myValue) => { // <-- note the `async` on this line
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
};
所以……如果不查看您的应用程序的其余部分就无法给出推荐,但取决于您要做什么,可以使 inner 函数异步或尝试为这个区块想出一些不同的架构。
更新:有一天我们可能会得到顶级等待:https://github.com/MylesBorins/proposal-top-level-await
你不能像你想象的那样做,因为你不能使用await
如果它不直接在async
函数中。
这里明智的做法是使传递给 map
的函数异步。这意味着 map
将 return 一组承诺。然后我们可以使用 Promise.all
来获得当所有承诺 return 时的结果。由于 Promise.all
本身 return 是一个承诺,外部函数不需要是 async
.
const someFunction = (myArray) => {
const promises = myArray.map(async (myValue) => {
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
return Promise.all(promises);
}
如果你想运行使用异步映射函数映射你可以使用下面的代码:
const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i)));
工作原理:
inputArray.map(async ...)
returns 一组承诺 - inputArray
中的每个值一个。
- 将
Promise.all()
放在 promise 数组周围会将其转换为单个 promise。
- 来自
Promise.all()
returns 一组值的单个承诺 - 每个承诺都解析为一个值。
- 我们将
await
放在 Promise.all()
前面,这样我们就可以等待合并的 promise 解析并将已解析的子 promises 数组存储到变量 resultArray
中。
最终我们在inputArray
中的每一项得到一个resultArray
中的输出值,通过函数someAsyncFunction
映射。在结果可用之前,我们必须等待所有异步函数解决。
这将是 2 条指令,但只需将“await”移至额外的指令
let results = array.map((e) => fetch('....'))
results = await Promise.all(results)
我尝试了所有这些答案,但没有人适合我的情况,因为所有答案 return 一个 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)
}
然后我找到了这个答案 ,它指出 map
函数是否不异步或承诺感知。
因此,我没有在 map
函数中使用 await
,而是使用 for
循环和 await
单个项目,因为他说 for
循环是 async
意识到并将暂停循环。
如果您希望在移动到下一个之前解决每个重新映射的值,您可以将数组作为异步迭代处理。
下面,我们使用库 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来解析每个生成的重映射值,以保持解析要求与原始问题一致。
我遇到此代码的编译时错误:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
return {
id: "my_id",
myValue: await service.getByValue(myValue);
}
});
};
错误信息是:
await is a reserved word
为什么我不能这样用?
我也试过另一种方法,但它给了我同样的错误:
const someFunction = async (myArray) => {
return myArray.map(myValue => {
const myNewValue = await service.getByValue(myValue);
return {
id: "my_id",
myValue: myNewValue
}
});
};
那是因为 map
中的函数不是 async,所以你不能在它的 await =28=]语句。它使用此修改进行编译:
const someFunction = async (myArray) => {
return myArray.map(async (myValue) => { // <-- note the `async` on this line
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
};
所以……如果不查看您的应用程序的其余部分就无法给出推荐,但取决于您要做什么,可以使 inner 函数异步或尝试为这个区块想出一些不同的架构。
更新:有一天我们可能会得到顶级等待:https://github.com/MylesBorins/proposal-top-level-await
你不能像你想象的那样做,因为你不能使用await
如果它不直接在async
函数中。
这里明智的做法是使传递给 map
的函数异步。这意味着 map
将 return 一组承诺。然后我们可以使用 Promise.all
来获得当所有承诺 return 时的结果。由于 Promise.all
本身 return 是一个承诺,外部函数不需要是 async
.
const someFunction = (myArray) => {
const promises = myArray.map(async (myValue) => {
return {
id: "my_id",
myValue: await service.getByValue(myValue)
}
});
return Promise.all(promises);
}
如果你想运行使用异步映射函数映射你可以使用下面的代码:
const resultArray = await Promise.all(inputArray.map(async (i) => someAsyncFunction(i)));
工作原理:
inputArray.map(async ...)
returns 一组承诺 -inputArray
中的每个值一个。- 将
Promise.all()
放在 promise 数组周围会将其转换为单个 promise。 - 来自
Promise.all()
returns 一组值的单个承诺 - 每个承诺都解析为一个值。 - 我们将
await
放在Promise.all()
前面,这样我们就可以等待合并的 promise 解析并将已解析的子 promises 数组存储到变量resultArray
中。
最终我们在inputArray
中的每一项得到一个resultArray
中的输出值,通过函数someAsyncFunction
映射。在结果可用之前,我们必须等待所有异步函数解决。
这将是 2 条指令,但只需将“await”移至额外的指令
let results = array.map((e) => fetch('....'))
results = await Promise.all(results)
我尝试了所有这些答案,但没有人适合我的情况,因为所有答案 return 一个 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)
}
然后我找到了这个答案 map
函数是否不异步或承诺感知。
因此,我没有在 map
函数中使用 await
,而是使用 for
循环和 await
单个项目,因为他说 for
循环是 async
意识到并将暂停循环。
如果您希望在移动到下一个之前解决每个重新映射的值,您可以将数组作为异步迭代处理。
下面,我们使用库 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来解析每个生成的重映射值,以保持解析要求与原始问题一致。