Bob*_*ole 3 javascript reduce asynchronous async-await
我正在开发一个使用 Array.reduce 的函数,并且需要在 reduce 函数内添加异步 API 调用。这要求我对传入的回调使用异步函数reduce
,因为我await
在函数内部使用它来等待异步 API 调用。
我在正确编写归约时遇到一些问题。这是目前的情况(工作):
const result = records.reduce((array, currValue) => {
//do stuff
return array
}, [])
Run Code Online (Sandbox Code Playgroud)
这是我尝试将其更改为:
const result = records.reduce(async(array, currentValue) => {
// do stuff
someValue = await asyncCall(currentValue)
array.add(someValue)
return array
}, [])
Run Code Online (Sandbox Code Playgroud)
我收到的错误是“没有与此调用匹配的重载”。
这对我来说似乎很有意义,因为reduce接受返回数组的回调,而异步函数返回回调,而不是数组。但是当我阅读如何将异步函数传递到 .reduce 的其他示例时,它们似乎都只是将异步函数传递到 reduce 中,没有任何问题。
以下是我查看的几个链接:
https://advancedweb.hu/how-to-use-async-functions-with-array-reduce-in-javascript/
JavaScript 数组 .reduce 与 async/await
https://gyandeeps.com/array-reduce-async-await/
当我将归约函数声明为异步时,我得到了不匹配重载错误,这对我来说是有意义的。我不确定这对其他人来说是否有效。
首先:reduce
可能不是为此使用的最佳工具。看起来您只是将条目添加到数组中。reduce
对于该任务来说过于复杂,特别是如果您正在执行异步操作。相反,可以在async
函数中使用的循环结构要简单得多。
我将从 开始reduce
,然后转到循环构造。
reduce
同步工作。如果您传递一个async
函数作为其回调,则该函数返回的承诺将是下一个回调看到的累加器值。因此,如果reduce操作中的一个步骤需要异步并返回一个promise,那么它之后的每一步都必须异步返回一个promise(为了简单起见,最好只让每一步都返回一个promise);will 的结果reduce
是对最终值的承诺,而不是最终值本身。您无法使异步调用同步,也无法使同步操作 ( reduce
) 等待异步结果。
因此,您的所有回调都将处理承诺。它看起来有点像这样:
\n\nconst result = await records.reduce(async(arrayPromise, currentValue) => {\n// \xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92^^^^^\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92^^^^^^^^^^^^\n const array = await arrayPromise // <=====\n // do stuff\n someValue = await asyncCall(currentValue)\n array.push(someValue) // <==== `push` rather than `add`, presumably\n return array\n}, Promise.resolve([]))\n// ^^^^^^^^^^^^^^^^\xe2\x88\x92\xe2\x88\x92^\n
Run Code Online (Sandbox Code Playgroud)\n\n当然,既然使用了await
,它就必须在一个async
函数中。否则:
records.reduce(async(arrayPromise, currentValue) => {\n const array = await arrayPromise // <=====\n // do stuff\n someValue = await asyncCall(currentValue)\n array.push(someValue)\n return array\n}, Promise.resolve([]))\n.then(result => {\n // ...use `result` here\n})\n.catch(error => {\n // ...handle/report error here...\n})\n
Run Code Online (Sandbox Code Playgroud)\n\n您最好使用本身支持成为async
函数一部分的循环构造:
const result = []\nfor (const currentValue of records) {\n someValue = await asyncCall(currentValue)\n result.push(someValue)\n}\n// ...use `result` here...\n
Run Code Online (Sandbox Code Playgroud)\n\n甚至
\n\nconst result = []\nfor (const currentValue of records) {\n result.push(await asyncCall(currentValue))\n}\n// ...use `result` here...\n
Run Code Online (Sandbox Code Playgroud)\n\n如果您需要在不是async
函数的函数中执行此操作,您将显式处理 Promise,如下所示:
(async () => {\n const result = []\n for (const currentValue of records) {\n result.push(await asyncCall(currentValue))\n }\n return result\n})()\n.then(result => {\n // ...use `result` here\n})\n.catch(error => {\n // ...handle/report error here...\n})\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
2623 次 |
最近记录: |