这段 js 代码的解释

48 天前
 anUglyDog

最近给我的 yimuc.com 整了个工具集的新功能,在搜寻工具库的时候发现了这个库async-pool。我自己工具站地址是这个:job.yimuc.com/online/toolkit介意的请不要点过去哈,浪费你时间

重点在这里,先上个 Github 电梯直达: https://github.com/rxaviers/async-pool/blob/master/lib/es9.js

不跳转也行,整个库就只有这一段代码,代码我也直接贴下面:

async function* asyncPool(concurrency, iterable, iteratorFn) {
  const executing = new Set();
  async function consume() {
    const [promise, value] = await Promise.race(executing);
    executing.delete(promise);
    return value;
  }
  for (const item of iterable) {
    // Wrap iteratorFn() in an async fn to ensure we get a promise.
    // Then expose such promise, so it's possible to later reference and
    // remove it from the executing pool.
    const promise = (async () => await iteratorFn(item, iterable))().then(
      value => [promise, value]
    );
    executing.add(promise);
    if (executing.size >= concurrency) {
      yield await consume();
    }
  }
  while (executing.size) {
    yield await consume();
  }
}

module.exports = asyncPool;

感觉这样处理很优雅啊,代码也很简洁。因为我正常写业务代码很少用generator function的,所以看了会觉得很新颖,他这里用了Promiseasync awaitgenerator function,外层调用它的时候还可以用for await()

学到了~

723 次点击
所在节点    程序员
4 条回复
anUglyDog
48 天前
为什么 V 站给我 markdown 行内代码反引号吞掉了
realJamespond
48 天前
刚好昨天撸了个类似的
```
export type Task = { (name: string): Promise<void> };
export async function queueStart(tasks: Task[], size = 1) {
const queue = (function* () {
for (let i = 0; i < tasks.length; i++) {
yield tasks[i];
}
})();
let finished = false;
const handle = async (name: string) => {
for (;;) {
const { done, value: task } = queue.next();
if (done) {
finished = true;
}
if (finished) {
break;
} else if (task) {
await task(name);
}
}
};
const joinAll: Promise<void>[] = [];
for (let i = 0; i < size; i++) {
const name = `thread-${i}`;
const join = handle(name).then(() => {
console.log(name, "end", new Date().toLocaleTimeString());
});
joinAll.push(join);
}
// return Promise.all(joinAll);
for (const join of joinAll) {
await join;
}
}

export function getTask(promise: Promise<unknown>): Task {
return async (name) => {
const begin = Date.now()
console.log(name, "task begin");
await promise;
console.log(name, "task done", (Date.now() - begin)*0.001);
};
}

// getTask(Promise.resolve(1))
// getTask(Promise.resolve("abc"))
// getTask(Promise.resolve({}))
```
anUglyDog
47 天前
@realJamespond 代码格式没了,不过看到 for(;;),我对你的代码性能存疑。
realJamespond
47 天前
for(;;)和 while true 不是一个意思?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1025884

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX