gpt4 book ai didi

javascript - Promise.all 消耗了我所有的内存

转载 作者:搜寻专家 更新时间:2023-10-31 22:44:38 27 4
gpt4 key购买 nike

我使用的 API 有一个速率限制器,它允许每秒 20 个请求。所有请求都是基于 promise 的,一旦有响应, promise 将通过 API 数据解决。

问题:

我设置了一个 promiseArray,其中包含 58k 个 promise ,所有这些都在等待响应。如此缓慢地内存增加,直到我内存不足。在我的特定情况下,我不需要将已解析的数据传递给我的 then(),并且数据会占用我所有的 RAM。

代码:

  }).then(() => {
// 2. Crawl for all clanprofiles from these leaderboards
const promiseArray = []
for (let i = 0; i < clanTags.length; i++) {
// Resolved data from getClanProfile() is eating up all my RAM
const p = backgroundScheduler.getClanProfile(clanTags[i], true)
promiseArray.push(p)
}
return Promise.all(promiseArray)
}).then(() => {

那么有没有一种方法可以等待直到 promiseArray 被解析而不需要解析的数据?

最佳答案

如果您从未有过 58k promise 、它们相关的异步操作和它们的结果数据同时处于事件状态,您将使用较少的内存量。

相反,您希望一次运行 X 个操作,然后当一个操作完成时,您开始下一个操作,同时在运行中的数量不超过 X 个,一次使用的 promise 也不超过 X 个。

您可以尝试使用适当的 X 值。值为 1 是顺序操作,但您通常可以通过使用更高的 X 值来缩短整体端到端操作时间。如果所有请求都访问同一主机,那么 X 可能不超过 5-10(因为给定的主机实际上不能一次做很多事情,要求它做的事情超过它一次可以做的事情只会减慢它的速度)。

如果每个请求都针对不同的主机,那么您可以使 X 更高。实验将为您提供峰值内存使用量和总体吞吐量的最佳值,这在一定程度上取决于您的具体情况。

Bluebird 的 Promise.map()有一个并发选项可以为您执行此操作,但也有许多方法可以同时仅针对飞行中的 X 进行编码。

以下是管理同时飞行的数量的一些其他编码示例:

Make several requests to an API that can only handle 20 request a minute

How to execute promises in series?

unable to complete promises due to out of memory

Fire off 1,000,000 requests 100 at a time

How to make it so that I can execute say 10 promises at a time in javascript to prevent rate limits on api calls?


如果您不需要已解析的数据,您可以像这样替换它以使其更快地被 GC 处理:

  const p = backgroundScheduler.getClanProfile(clanTags[i], true).then(data => {
return 0; // make resolved value just be a simple number
// so other data is now eligible for GC
});
promiseArray.push(p)

并且,这是一个简单的实现,它迭代一个数组,同时处理的请求不超过 X 个:

// takes an array of items and a function that returns a promise
// runs no more than maxConcurrent requests at once
function mapConcurrent(items, maxConcurrent, fn) {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;

return new Promise(function(resolve, reject) {

function runNext() {
let i = index;
++inFlightCntr;
fn(items[index], index++).then(function(val) {
++doneCntr;
--inFlightCntr;
results[i] = val;
run();
}, function(err) {
// set flag so we don't launch any more requests
stop = true;
reject(err);
});
}

function run() {
// launch as many as we're allowed to
while (!stop && inFlightCntr < maxConcurrent && index < items.length) {
runNext();
}
// if all are done, then resolve parent promise with results
if (doneCntr === items.length) {
resolve(results);
}
}

run();
});
}

关于javascript - Promise.all 消耗了我所有的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46654265/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com