【问题标题】:waiting on 2 (or more) async generators simultaneously [duplicate]同时等待2个(或更多)异步生成器[重复]
【发布时间】:2018-11-12 10:48:43
【问题描述】:

我已经为此苦苦挣扎了一段时间。

如果给定 n 个异步生成器,您将如何编写一个异步生成器,按照它们到达的顺序从 n 个生成器中生成值。

该方法应采用以下格式: const merged = merge([gen1, gen2,...])

例如:

gen1 and gen2 are async generators.
gen1() yields 2 values: 1 in 100ms, 3 in 300ms  
gen2() yields 2 values: 2 in 200ms, 4 in 400ms

merge([gen1, gen2]) will yield 1, 2, 3, 4 (in that order, every 100ms)

【问题讨论】:

  • 很难!感觉 Promise.race 可能是正确的工具?
  • 我试过了!这太难了:)我已经尝试了好几天了

标签: javascript asynchronous generator yield


【解决方案1】:

所以... 经过几天的努力解决这个问题。 这有效(只需将粘贴复制到最新的 chrome 并打开实验标志)

function timer(time = 500) {
  return new Promise(resolve => setTimeout(() => resolve(), time));
}

async function* gen1() {
  await timer(100);
  yield 1;
  await timer(300);
  yield 4;
}

async function* gen2() {
  await timer(200);
  yield 2;
  await timer(100);
  yield 3;
}

function race(promises) {
  return new Promise(resolve =>
    promises.forEach((p, index) => {
      p.then(value => {
        resolve({index, value});
      });
    })
  );
}
async function* mergen(...gens) {
  let promises = gens.map((gen, index) =>
    gen.next().then(p => ({...p, gen}))
  );

  while (promises.length > 0) {
    yield race(promises)
    .then(({index, value: {value, done, gen}}) => {
      promises.splice(index, 1);
      if (!done)
        promises.push(
          gen.next().then(({value: newVal, done: newDone}) => ({
            value: newVal,
            done: newDone,
            gen
          }))
        );
      return value;
    });
  }
}

async function printGen(gen) {
  let max = 10;
  for await (x of gen) {
    if (x) console.log('Next up:', x);
    if (--max <= 0) break;
  }
}

printGen(mergen(gen1(), gen2())); // 1, 2, 3, 4

这是预重构,所以请记住它还不是很好和干净。 有趣的代码叫做mergen()(明白了吗?merge-gen?) 它也使用此处包含的Promise.race() 的修改版本。 使用修改后的race 的原因是因为我需要先完成promise 的索引。

更新:现在它是一个 npm 模块 https://github.com/hesher/mergen

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 2017-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    相关资源
    最近更新 更多