How can I Interleave / merge async iterables?

后端 未结 5 1294
抹茶落季
抹茶落季 2020-12-15 06:51

Suppose I have some asnyc iterable objects like this:

// Promisified sleep function
const sleep = ms => new Promise((resolve, reject) => {
  setTimeou         


        
5条回答
  •  南方客
    南方客 (楼主)
    2020-12-15 07:46

    I solved this using async generators. (I wish I'd find this question a few days ago, would save me some time) Will gladly hear opinion and criticism.

    async function* mergen(...gens) {
      const 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;
        });
      }
    };
    
    // Needed to implement race to provide index of resolved promise
    function race(promises) {
      return new Promise(resolve =>
        promises.forEach((p, index) => {
          p.then(value => {
            resolve({index, value});
          });
        })
      );
    }
    

    It took me a bunch of time to find and I got so excited I put it in a npm package :) https://www.npmjs.com/package/mergen

提交回复
热议问题