Skip to content

Instantly share code, notes, and snippets.

@Bnaya
Created March 11, 2018 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bnaya/d83d5ded07bc8cf6002dffbb2fa78dff to your computer and use it in GitHub Desktop.
Save Bnaya/d83d5ded07bc8cf6002dffbb2fa78dff to your computer and use it in GitHub Desktop.
You might not need promise/async helper library after all
// You probobly don't need a helper library for Promise/Async after all
const seedValues = [Promise.resolve(777), Promise.resolve(888)];
// reduce
// Promise based
seedValues
.reduce((accumulator, currentValue) =>
accumulator.then(v => currentValue.then(cv => v + cv))
)
.then(console.log.bind(console));
// async
seedValues
.reduce(async (acc, c) => (await acc) + (await c))
.then(console.log.bind(console));
// simple map
// Promise based
Promise.all(seedValues.map(p => p.then(v => v.toString()))).then(
console.log.bind(console)
);
// async
Promise.all(seedValues.map(async p => (await p).toString())).then(
console.log.bind(console)
);
// map with concurrency (Similar to bluebird's map)
const concurrency = 4;
const control = {
pipelines: new Array<Promise<void>>(4).fill(Promise.resolve()),
values: [] as string[]
};
for (let i = 0; i < seedValues.length; i++) {
control.pipelines[i % concurrency] = control.pipelines[i % concurrency].then(() => {
return seedValues[i].then((seed) => {
control.values.push(seed.toString());
// or will keep us stable!
// control.values[i] = seed.toString();
});
});
}
Promise.all(control.pipelines).then(() => control.values);
// cancellation?
// use AbortController! or similar cancellation token mechnizem
/// https://developer.mozilla.org/en-US/docs/Web/API/AbortController
@Bnaya
Copy link
Author

Bnaya commented Apr 28, 2018

function forEach<T, R>(arr: T[], pr: (p: T) => Promise<R>, concurrency: number = 1) {
  return new Promise<R[]>(function (res, rej) {
    let error = false;
    const toReturn: R[] = [];
    let workers = 0;

    function beat(r: R) {
      if (error) {
        return;
      }

      toReturn.push(r);
      workers--;
      const v = arr.pop();

      if (v) {
        pr(v).then(beat).catch((e) => { error = true; rej(e) });
        workers++;
      } else if (toReturn.length === arr.length) {
        res(toReturn);
      }
    }

    for (workers < concurrency; workers++;) {
      const v = arr.pop();

      // incase that concurrency > arr.length
      if (v) {
        pr(v).then(beat).catch(() => error = true);
      }
    }
  });
}

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