补全及实现一下函数
let executeCount = 0;
const targetFn = async nums => {
executeCount++;
return nums.map(num => 2 * num + 1);
};
const batcher = (fn) => {
// todo batch logic
return () => {
}
}
const batchedFn = batcher(targetFn);
const main = async () => {
const [result1, result2, result3] = await Promise.all([
batchedFn([1, 2, 3]),
batchedFn([4, 5]),
batchedFn([6, 7]),
]);
console.log(result1, result2, result3)
console.log(executeCount) // 预期为 1
}
main()
解答:
在 graphql/loader1 以及 trpc2 中均有关于 batch 的实现,意在提升性能,将多次 IO 合并为一次 IO
其关键在于一次事件循环中的微任务队列存储所有的 batchKeys。
代码片段及执行结果见码上掘金3
const batcher = (fn) => {
// todo batch logic
let allArgs = []
// 能够实现 batch 的关键所在
// 此处 fn(allArgs) 甚至可以实现为 fn([...new Set(allArgs)]),性能更好一些
const wait = Promise.resolve().then(() => fn(allArgs))
return async (args) => {
allArgs = [...allArgs, ...args]
const result = await wait
// allArgs 与 result 形成的一个 Map
// 借助于 lodash 可以更可读化地写成 Object.fromEntries(_.zip(allArgs, result))
const resultMap = result.reduce((acc, x, i) => {
const v = allArgs[i]
acc[v] = x
return acc
}, {})
return args.map(a => resultMap[a])
}
}
参考资料
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8