Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Q743】实现 batchFn 函数,可以批量执行函数 #800

Open
shfshanyue opened this issue May 18, 2023 · 4 comments
Open

【Q743】实现 batchFn 函数,可以批量执行函数 #800

shfshanyue opened this issue May 18, 2023 · 4 comments

Comments

@shfshanyue
Copy link
Owner

补全及实现一下函数

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()
@shfshanyue
Copy link
Owner Author

shfshanyue commented May 18, 2023

graphql/loader 以及 trpc 中均有关于 batch 的实现,意在提升性能,将多次 IO 合并为一次 IO

其关键在于一次事件循环中的微任务队列存储所有的 batchKeys。

代码片段及执行结果见码上掘金

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])
  }
}

@shfshanyue shfshanyue added the js label Aug 5, 2023
@MJWade96
Copy link

MJWade96 commented Mar 3, 2024

运行结果好像是输出 3 个 [3, 5, 7],返回的 promiseargs 应该都指向了第一次调用时传入的参数

@MJWade96
Copy link

MJWade96 commented Mar 3, 2024

网上看到了另一种解法:SegmentFault

@shfshanyue shfshanyue added the code label Mar 3, 2024
@shfshanyue
Copy link
Owner Author

@MJWade96 已修复,并配上相应的注释、码上掘金的 Playground 以及相关源码参考。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants