Last active
February 19, 2020 00:43
-
-
Save developit/7a6e48654b88002a835f8f6bc4535a6d to your computer and use it in GitHub Desktop.
Async Array utilities in async/await. Now available as an npm package: https://github.com/developit/asyncro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Async version of Array.prototype.reduce() | |
* await reduce(['/foo', '/bar', '/baz'], async (acc, v) => { | |
* acc[v] = await (await fetch(v)).json(); | |
* return acc; | |
* }, {}); | |
*/ | |
export async function reduce(arr, fn, val, pure) { | |
for (let i=0; i<arr.length; i++) { | |
let v = await fn(val, arr[i], i, arr); | |
if (pure!==false) val = v; | |
} | |
return val; | |
} | |
/** Async version of Array.prototype.map() | |
* await map(['foo', 'baz'], async v => await fetch(v) ) | |
*/ | |
export async function map(arr, fn) { | |
return await reduce(arr, (acc, value, index, arr) => { | |
acc.push(await fn(value, index, arr)); | |
}, [], false); | |
} | |
/** Async version of Array.prototype.filter() | |
* await filter(['foo', 'baz'], async v => (await fetch(v)).ok ) | |
*/ | |
export async function filter(arr, fn) { | |
return await reduce(arr, (acc, value, index, arr) => { | |
if (await fn(value, index, arr)) acc.push(value); | |
}, [], false); | |
} | |
function identity(x) { | |
return x; | |
} | |
function resolve(list) { | |
let out = Array.isArray(list) ? [] : {}; | |
for (let i in list) if (list.hasOwnProperty(i)) out[i] = list[i](); | |
return out; | |
} | |
/** Provided by standard lib, replaces async.parallel() | |
* await parallel([ | |
* () => fetch('foo'), | |
* () => fetch('baz') | |
* ]) | |
*/ | |
export async function parallel(list) { | |
return await Promise.all(resolve(list)); | |
} | |
/** Replaces async.series() | |
* await series([ | |
* () => fetch('foo'), | |
* () => fetch('baz') | |
* ]) | |
*/ | |
export async function series(list) { | |
return await map(resolve(list), identity); | |
} |
@jethrolarson - correct, reduce is being given a fourth argument here that ignores return values and instead uses a pass-by-reference accumulator only.
@dbrockman good catch! I've updated the gist to invoke those methods.
What do you think about changing the order of arguments, i.e. data comes last (like in Ramda)? :-)
@dpraimeyuu to simplify partial application?
@developit I think that, and make it works with pipes if we ever get them.
This is really cool and I've learned a lot already.
Thanks for putting this together and sharing it with the community! You rock!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The functions you're passing to reduce aren't returning anything