V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
anUglyDog
V2EX  ›  程序员

这段 js 代码的解释

  •  
  •   anUglyDog · 36 天前 · 706 次点击
    这是一个创建于 36 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近给我的 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()

    学到了~

    4 条回复
    anUglyDog
        1
    anUglyDog  
    OP
       36 天前
    为什么 V 站给我 markdown 行内代码反引号吞掉了
    realJamespond
        2
    realJamespond  
       36 天前
    刚好昨天撸了个类似的
    ```
    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
        3
    anUglyDog  
    OP
       36 天前
    @realJamespond 代码格式没了,不过看到 for(;;),我对你的代码性能存疑。
    realJamespond
        4
    realJamespond  
       36 天前
    for(;;)和 while true 不是一个意思?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2688 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:18 · PVG 19:18 · LAX 04:18 · JFK 07:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.