【问题标题】:ES6: Filter array in chunks to not freeze the UIES6:过滤数组以不冻结 UI
【发布时间】:2018-06-20 10:51:09
【问题描述】:

我正在尝试过滤一个巨大的数组。不幸的是,数组太大以至于 UI 冻结。这就是为什么我尝试分块执行过滤,中间有一个超时,以便 UI 可以加载。

出于演示目的,我采用“巨大”数组[1,2,3,4,5] 并返回可被二整除的元素。

我试过了,但是不行:

[1,2,3,4,5].filter(async (x) => {
    // wait 1 sec after each element to filter
    await new Promise(resolve => setTimeout(resolve, 1000));
    return x % 2 === 0;
});

任何想法如何过滤大数组以使 UI 不会冻结?

【问题讨论】:

标签: javascript arrays filter ecmascript-6


【解决方案1】:

Array.prototype.filter 不能与 async 谓词一起使用,因为谓词必须返回布尔值,但 async 谓词将返回一个承诺。

您可以使用Array.prototype.reduce 链接您的异步调用并自己构建过滤结果。

async function filterAsync(array, predicate) {
    const res = [];

    await array.reduce(async (promise, n) => {
        await promise;
        if (await predicate(n)) {
            res.push(n);
        }
    }, Promise.resolve());

    return res;
}


filterAsync([1, 2, 3, 4, 5], async x => {
    // wait 1 sec after each element to filter
    await new Promise(resolve => setTimeout(resolve, 1000));
    return x % 2 === 0;
}).then(console.log);

【讨论】:

    【解决方案2】:

    您可以异步方式用过滤后的元素填充空数组,需要注意的是顺序可能与原始数组不同:

    var ret = []
    var promiseArray = [1,2,3,4,5].map( async x => {
        await new Promise(resolve => {setTimeout(resolve, 1000)})
        if (x % 2 === 0) {
            ret.push(x)
        }
    })
    Promise.all(promiseArray).then(()=> {console.log(ret)})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      相关资源
      最近更新 更多