TLDR: This article introduces the arrays-sugar library: https://github.com/samuelkarani/arrays-sugar
Why won't this work correctly in javascript?
const array = [1, 7, 3]
array.every(async (number) => number > 1) // returns true instead of false
array.filter(async (number) => number > 1) // returns [1, 7, 3] instead of ?
array.find(async (number) => number > 1) // returns 1 instead of ?
array.findIndex(async (number) => number > 1) // returns 0 instead of ?
array.some(async (number) => number > 7) // returns true instead of ?
All these return incorrect values because the async makes the callback return a promise which always returns truthy when evaluated.
While map is happy to give you as many promises as you want:
array.map(async (number) => number * 2)
// [ Promise { 2 }, Promise { 14 }, Promise { 6 } ]
And reduce works with both promise and async/await callbacks:
const numbers = [1, 2, 3, 4, 5];
const sum1 = await numbers.reduce((accumulator, number) => {
return accumulator.then(value => value + number)
}, Promise.resolve(0));
// sum1 is 15
const sum2 = await numbers.reduce(async (accumulator, number) => {
await sleep(10) // wraps setTimeout
return (await accumulator) + number;
}, Promise.resolve(0))
// sum2 is 15
Introducing my new library: arrays-sugar - a set of async versions of every, filter, find, findIndex, some
Build with Typescript for the Browser or Node.js
Each function has 2 or 3 versions:
The default version that is concurrent and uses Promise.allSettled internally:
// both are equivalent
[1, 2, 3].every(async (number) => number === 2) === true
[1, 2, 3].everyConcurrent(async (number) => number === 2) === true
The optimized version which may not iterate the entire array and requires that the predicate throws for falsy values instead of returning false. This is available for all functions except filter which has to go through the whole array.
const result = await findOptimized(array, async (item) => {
if (item <= 1) {
throw new Error("error");
}
return true;
});
The serial version that iterates each item one at a time (slow) - incase this is what you want to do.
const result = await findIndexSerial(array, async (item) => {
await sleep(100);
return item > 1;
});
That's all
Thanks for reading. I welcome your input, suggestions, feedback.
Github link: https://github.com/samuelkarani/arrays-sugar
NPM link: https://www.npmjs.com/package/arrays-sugar
One more thing
You can check out the related library AI Sugar where these functions are used internally to work with AI APIs.
Top comments (0)