These functions get an iteratee function, just like the filter
, but they return a single true/false, depending on whether the predicate returned a specific value. In the case of the some
, if any of the predicates returned true, the result will be true. For the every
function, if any returned false, the result will be false.
const arr = [1, 2, 3];
const someRes = arr.some((i) => {
return i % 2 === 0;
});
console.log(someRes);
// true
const everyRes = arr.every((i) => {
return i < 2;
});
console.log(everyRes);
// false
Considering only the result, these functions can be emulated with an async filter
, which is already covered in a previous article how to convert to async.
// sync
const some = (arr, predicate) =>
arr.filter(predicate).length > 0;
const every = (arr, predicate) =>
arr.filter(predicate).length === arr.length;
// async
const asyncSome = async (arr, predicate) =>
(await asyncFilter(arr, predicate)).length > 0;
const asyncEvery = async (arr, predicate) =>
(await asyncFilter(arr, predicate)).length === arr.length;
But there is an important difference between the built-in some
/every
functions and the filter
-based implementations. When there is an element that returns true for a some
, it short-circuits and does not process the remaining elements:
const arr = [1, 2, 3];
const res = arr.some((i) => {
console.log(`Checking ${i}`);
return i % 2 === 0;
});
// Checking 1
// Checking 2
console.log(res);
// true
Similarly, every
stops after the first false result:
const arr = [1, 2, 3];
const res = arr.every((i) => {
console.log(`Checking ${i}`);
return i < 2;
});
// Checking 1
// Checking 2
console.log(res);
// false
Let's see how to code an async version that works in a similar way and does the least amount of work!
The best solution is to use an async for iteration that returns as soon as it finds a truthy result: