当前位置: 首页 > 知识库问答 >
问题:

许诺我的公羊都吃光了

欧阳安阳
2023-03-14

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

问题是:

我设置了一个promise数组,其中包含58kpromise都在等待响应。所以慢慢地内存增加,直到我运行内存溢出。在我的特定情况下,我不需要将解析的数据传递给我的然后(),这些数据正在消耗我所有的内存。

守则:

  }).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(() => {

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

共有1个答案

井翰
2023-03-14

如果您没有58kpromise、它们关联的异步操作和它们的结果数据同时处于活动状态,那么您将使用更少的内存。

相反,你想一次运行X个操作,然后当一个操作完成时,你开始下一个操作,同时不会超过X个,也不会超过X个promise同时使用。

您可以尝试使用适当的值X。值1表示顺序操作,但通常可以通过使用更高的值X来提高整体端到端操作时间。如果所有请求都命中同一主机,则X可能不超过5-10(因为一个给定的主机不能一次真正做很多事情,而要求它做比它一次能做的更多的事情只会让它慢下来)。

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

蓝鸟的promise。map()有一个并发选项,可以为您实现这一点,但也有许多方法可以同时为飞行中的X编码。

下面是一些其他编码示例,用于管理一次飞行的飞机数量:

对一个每分钟只能处理20个请求的API发出多个请求

如何执行一系列的promise?

由于内存溢出无法完成promise

一次发出1000000个请求100个

如何使我可以在javascript中一次执行10个promise,以防止api调用的速率限制?

如果您不需要已解析的数据,您可以通过如下方式替换它,使其能够更快地进行GCD:

  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();
    });
}
 类似资料:
  • 下面是我的异步函数从DB中读取值并在控制台上记录一些东西。但由于某种原因它没有发生。 因此,我创建了一个许诺数组,然后继续等待所有许诺的解决,因为许诺将从DB读取。但await on promission.all不是暂停代码的执行,也不是等待all promission解析,而是将控制权传递回调用函数。我这里有没有遗漏什么东西? 以上调用的输出为: 理想情况下,输出应该在下面(因为我正在等待所有的

  • 问题内容: 为了在数据库中创建对象,我已经创建了许多许诺。 最后,我要按我想要的顺序履行所有诺言。(因为somes对象依赖于其他对象,所以我需要保持该顺序) 所以我希望看到: 不幸的是,这些消息被打乱了,我不明白。 谢谢 问题答案: 看起来您理解了Promise错误,请重新阅读有关Promise和本文的一些教程。 使用创建承诺后,它会立即被调用,因此所有函数实际上都是在创建它们时执行的,而不是在链

  • 按照我找到的这个教程,我一直在Unity(C#)中创建了一个简单的贪吃蛇游戏: https://www.youtube.com/watch?v=U8gUnpeaMbQ 我发现这是一个非常好的教程,到最后我有一个完美的蛇游戏,但是,我想走得更远一点,使运动更加愉快,添加尾巴,Gameover等。 现在我的问题是,如果一个玩家快速连续按下两个可接受的方向试图抓住一些食物,蛇的头会跳过食物,完全错过它。

  • 问题内容: 所以我在angularjs服务器中有一个方法,该方法正在调用为数组中的每个方法返回promise的方法。我正在使用下划线_each遍历数组。我想等到整个数组都处理完后再在方法中调用代码的最后一行。 所以… 这当然是行不通的。.循环完成,并在为每个项目完成makeStuffCooler之前调用“ ShowAllMyCoolStuff”。那么..与async方法交互的正确方法是什么,这样我

  • 我想建立一个詹金斯大师,让奴隶们做所有的建造。 主人只是一个交通警察,获取SVN钩子触发器并启动从构建。 在这个设置中大约有10JavaMaven构建作业。 我希望在资源有限的托管服务器(RAM)上运行Jenkins主服务器。 我将在我自己的网络上运行一些加载良好的机器上的奴隶。 所以我的问题是,分配给Master Jenkins实例的内存有多小?2.56亿?3.84亿美元?5.12亿?另外 我在

  • 我正在建立身份管理系统,我想让它像Fabric-indy一样被允许-公共。有人建议我使用hyperledger indy,但我想在hyperledger-fabric上建立一个被允许-私人的允许-公共系统。有可能吗?