ken*_*tor 6 javascript node.js bluebird
我有一个我正在使用的API的速率限制器,它允许每秒20个请求.所有请求都是基于承诺的,一旦有响应,承诺将通过API数据解决.
问题:
我设置了一个promiseArray,它包含所有等待响应的58k承诺.所以内存越来越慢,直到我的内存耗尽为止.在我的具体情况下,我不需要将已解析的数据传递给我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(() => {
Run Code Online (Sandbox Code Playgroud)
那么有没有办法等待promiseArray被解析而不需要解析数据?
如果您没有 58k 承诺、它们关联的异步操作和它们的结果数据同时处于活动状态,那么您将使用较少的内存。
相反,您希望一次运行 X 个操作,然后当一个操作完成时,您开始下一个操作,同时在运行中永远不会超过 X,并且一次使用的承诺永远不会超过 X。
您可以尝试使用适当的 X 值。值为 1 是顺序操作,但您通常可以通过使用更高的 X 值来改善整体端到端操作时间。如果所有请求都访问同一主机,则 X 是可能不超过 5-10 个(因为一个给定的主机不能一次真正做很多事情,并且要求它做的比它一次做的更多只会减慢它的速度)。
如果每个请求都发送到不同的主机,那么您可以将 X 设置得更高。实验将为您提供峰值内存使用和总吞吐量的最佳值,并且在某种程度上取决于您的具体情况。
BluebirdPromise.map()
有一个并发选项可以为您执行此操作,但也有多种方法可以同时为 X 进行编码。
以下是管理一次飞行数量的其他一些编码示例:
如何做到这一点,以便我可以在 javascript 中一次执行 10 个承诺,以防止对 api 调用进行速率限制?
如果你不需要解析的数据,你可以通过像这样替换它来让它更快地被 GCed:
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)
Run Code Online (Sandbox Code Playgroud)
而且,这是一个简单的实现,它迭代一个数组,同时不超过 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();
});
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1032 次 |
最近记录: |