Fla*_*nix 27 javascript arrays filter async-await
我试图过滤一个对象数组.在我过滤之前,我需要将它们转换为某种格式,并且此操作是异步的.
const convert = () => new Promise( resolve => {
setTimeout( resolve, 1000 );
});
Run Code Online (Sandbox Code Playgroud)
所以,我的第一次尝试是使用async/await执行以下操作:
const objs = [ { id: 1, data: "hello" }, { id: 2, data: "world"} ];
objs.filter( async ( obj ) => {
await convert();
return obj.data === "hello";
});
Run Code Online (Sandbox Code Playgroud)
现在,正如你们中的一些人所知,Array.protoype.filter回调必须返回true或false的函数.filter是同步的.在前面的例子中,我没有返回它们,我返回一个Promise(所有异步函数都是Promises).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
因此,正如人们可以假设的那样,之前的代码并没有真正起作用......这种假设是正确的.
为了使过滤器使用异步函数,我检查了stackoverflow并找到了这个主题:
不幸的是,选择的答案过于复杂并且使用了类.这不适合我.我正在寻找一个更简单的解决方案,使用功能方法的简单功能.
最后有一个解决方案,使用带回调的地图来模拟过滤器:
但我希望修复我的过滤功能,而不是替换它.
小智 25
没有办法使用具有异步功能的过滤器(至少我知道).您必须使用带有promise集合的过滤器的最简单方法是使用Promise.all然后将该函数应用于您的结果集合.它看起来像这样:
const results = await Promise.all(your_promises)
const filtered_results = results.filter(res => //do your filtering here)
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
改编自文章How to use async functions with Array.filter in Javascript by Tamás Sallai,您基本上有两个步骤:
这是一个例子
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
Run Code Online (Sandbox Code Playgroud)