首页 > 解决方案 > 如何尽可能快地运行多个异步函数(JS)?

问题描述

如果给你一个异步函数数组,并且任务是创建一个类,该类接受这个数组并尽可能快地运行函数,并限制只能同时运行 15 个函数,那么该怎么做那?

如果对功能没有限制15,我相信Promise.all这将是可行的方法。

使用 justasync/await并等待一个函数解析来添加下一个函数非常慢,因为我们必须等待 1 个函数解析,直到我们可以添加另一个函数,因此我们可以有一个瓶颈函数。

15函数添加到数组并在解析后运行它们Promise.all,添加另一个15或其余的,同样不是很有效,因为我们想要做的是在其中一个函数解析后立即调用另一个函数。

有任何想法吗?

标签: javascriptasynchronousasync-awaites6-class

解决方案


这是我在过去 20 分钟内制作的东西,应该可以完成这项工作

我敢肯定,如果我考虑过它,我可能可以在没有 Promise 构造函数的情况下做到这一点,但是...... 20 分钟就是 20 分钟:p

拜托,如果有人可以在没有 Promise 构造函数的情况下重写它,我很乐意看到它 - 因为在我的脑海中,我确信有办法

请注意,无论拒绝如何,这都会运行

结果将是

result: actualResult

或者

error: rejectionReason

所以你可以处理结果/拒绝

function runPromises(arrayOfFunctions, maxLength) {
    return new Promise(resolve => {
        const queue = arrayOfFunctions.map((fn, index) => ({fn, index}));
        const results = new Array(arrayOfFunctions.length);
        let finished = 0;
        const doQ = () => {
            ++finished;
            if (queue.length) {
                const {fn, index} = queue.shift();
                fn()
                .then(result => results[index] = {result})
                .catch(error => results[index] = {error})
                .finally(doQ);
            } else {
                if (finished === arrayOfFunctions.length) {
                    resolve(results);
                }
                
            }
        };
        queue.splice(0, maxLength).forEach(({fn, index}) => fn()
            .then(result => results[index] = {result})
            .catch(error => results[index] = {error})
            .finally(doQ)
        );
    });
}
//
// demo and show that maximum 15 inflight requests
//
let inFlight = 0;
let maxInFlight = 0;
const fns = Array.from({length:50}, (_, i) => {
    return () => new Promise(resolve => {
      ++inFlight;
      maxInFlight = Math.max(inFlight, maxInFlight);
      setTimeout(() => {
        --inFlight;
        resolve(i);
      }, Math.random() * 200 + 100,)
    });
});
runPromises(fns, 15).then(results => console.log(maxInFlight, JSON.stringify(results)));


推荐阅读