如何解决通过使用 async/await
代码中使用的变量和函数:
const fakeAPI = (delay,value) =>
new Promise(resolve => setTimeout(() => resolve(value),delay));
const useResult = x => console.log(new Date(),x);
此代码通过使用 reduce() 实现来打印 forEach 不能通过异步调用实现的内容:
const forEachAsync = (arr,fn) =>
arr.reduce(
(promise,value) => promise.then(() => fn(value)),Promise.resolve()
);
(async () => {
console.log("START FOREACH VIA REDUCE");
await forEachAsync([1,2,3,4],async n => {
const x = await fakeAPI(n * 1000,n);
useResult(x);
});
console.log("END FOREACH VIA REDUCE");
})();
输出
/*
START FOREACH VIA REDUCE
2019-10-13T20:02:23.437Z 1
2019-10-13T20:02:24.446Z 2
2019-10-13T20:02:25.949Z 3
2019-10-13T20:02:27.952Z 4
END FOREACH VIA REDUCE
*/
主代码块上下文中arr.reduce
函数中promise和value参数的作用是什么?
value 参数是否传递给了 async n 箭头函数?
尽管如此,我更喜欢解释,因为我正在研究功能程序,但是,如果有任何其他方式以 FP 方式处理此问题,我将不胜感激。
解决方法
forEach
forEach
是您正在研究的代码不好的副作用。该示例使用 async
和 await
,因此使用 .reduce
链接 .then
调用是没有意义的。也就是说,如果你想体验它的使用痛苦,我们可以实现它 -
async function forEach (arr,fn)
{ for (const x of arr)
await fn(x) // <- return value of fn disappears
}
const sleep = ms =>
new Promise(r => setTimeout(r,ms))
const fakeApi = x =>
sleep(1000).then(_ => `api response: ${x * x}`)
forEach
( [1,2,3,4],async x =>
// side effect tangled with task processing code
console.log((new Date).toUTCString(),await fakeApi(x))
)
.then(console.log,console.error) // <- no values beyond this point
"Sat,30 Jan 2021 16:46:35 GMT" "api response: 1" // <- :35
"Sat,30 Jan 2021 16:46:36 GMT" "api response: 4" // <- :36
"Sat,30 Jan 2021 16:46:37 GMT" "api response: 9" // <- :37
"Sat,30 Jan 2021 16:46:38 GMT" "api response: 16" // <- :38
undefined
要解决上述问题,请注意 serial
和 parallel
(如下)如何将数据保存在 内 承诺中,而不是使用 {{ 1}} 或 console.log
。
串行
我们可以写useResult
,它以串行顺序处理任务-
serial
async function serial (arr,fn)
{ let r = []
for (const x of arr)
r.push(await fn(x))
return r
}
const sleep = ms =>
new Promise(r => setTimeout(r,ms))
const fakeApi = x =>
sleep(1000).then(_ => `api response: ${x * x}`)
serial
( [1,async x => [ (new Date).toUTCString(),await fakeApi(x) ]
)
.then(console.log,console.error)
平行
或者我们可以写[
[
"Sat,30 Jan 2021 16:39:04 GMT",// <- :04
"api response: 1"
],[
"Sat,30 Jan 2021 16:39:05 GMT",// <- :05
"api response: 4"
],30 Jan 2021 16:39:06 GMT",// <- :06
"api response: 9"
],30 Jan 2021 16:39:07 GMT",// <- :07
"api response: 16"
]
]
,它以并行-
parallel
const parallel = (arr,fn) =>
Promise.all(arr.map(v => fn(v)))
const sleep = ms =>
new Promise(r => setTimeout(r,ms))
const fakeApi = x =>
sleep(1000).then(_ => `api response: ${x * x}`)
parallel
( [1,console.error)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。