How to use Array.prototype.filter with async?
There is no way to use filter with an async function (at least that I know of).The simplest way that you have to use filter with a collection of promises is to use Promise.all
and then apply the function to your collection of results.It would look something like this:
const results = await Promise.all(your_promises)const filtered_results = results.filter(res => //do your filtering here)
Hope it helps.
Adapted from the article How to use async functions with Array.filter in Javascript by Tamás Sallai, you basically have 2 steps:
- One that creates the conditions for an object to pass
- One that receives the objects and returns true or false according to conditions
Here's an example
const arr = [1, 2, 3, 4, 5];function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }const asyncFilter = async (arr, predicate) => { const results = await Promise.all(arr.map(predicate)); return arr.filter((_v, index) => results[index]);}const asyncRes = await asyncFilter(arr, async (i) => { await sleep(10); return i % 2 === 0;});console.log(asyncRes);// 2,4
Use Scramjet fromArray/toArray methods...
const result = await scramjet.fromArray(arr) .filter(async (item) => somePromiseReturningMethod(item)) .toArray();
as simple as that - here's a ready example to copy/paste:
const scramjet = require('../../');async function myAsyncFilterFunc(data) { return new Promise(res => { process.nextTick(res.bind(null, data % 2)); });}async function x() { const x = await scramjet.fromArray([1,2,3,4,5]) .filter(async (item) => myAsyncFilterFunc(item)) .toArray(); return x;}x().then( (out) => console.log(out), (err) => (console.error(err), process.exit(3)) // eslint-disable-line);
Disclamer: I am the author of scramjet. :)