小编典典

使用 ES6 的 Promise.all() 时限制并发的最佳方法是什么?

all

我有一些代码正在遍历从数据库中查询出来的列表,并为该列表中的每个元素发出 HTTP
请求。该列表有时可能是相当大的数字(以数千计),我想确保我不会访问具有数千个并发 HTTP 请求的 Web 服务器。

此代码的缩写版本目前看起来像这样......

function getCounts() {
  return users.map(user => {
    return new Promise(resolve => {
      remoteServer.getCount(user) // makes an HTTP request
      .then(() => {
        /* snip */
        resolve();
      });
    });
  });
}

Promise.all(getCounts()).then(() => { /* snip */});

此代码在节点 4.3.2 上运行。重申一下,可以Promise.all进行管理,以便在任何给定时间只有一定数量的 Promise 正在进行?


阅读 150

收藏
2022-08-19

共1个答案

小编典典

请注意,Promise.all()它不会触发 Promise 开始工作,而是创建 Promise 本身。

考虑到这一点,一种解决方案是在解决承诺时检查是否应该开始新的承诺,或者您是否已经达到极限。

但是,这里真的没有必要重新发明轮子。您可以用于此目的的一个库是es6-promise- pool. 从他们的例子中:

var PromisePool = require('es6-promise-pool')

var promiseProducer = function () {
  // Your code goes here. 
  // If there is work left to be done, return the next work item as a promise. 
  // Otherwise, return null to indicate that all promises have been created. 
  // Scroll down for an example. 
}

// The number of promises to process simultaneously. 
var concurrency = 3

// Create a pool. 
var pool = new PromisePool(promiseProducer, concurrency)

// Start the pool. 
var poolPromise = pool.start()

// Wait for the pool to settle. 
poolPromise.then(function () {
  console.log('All promises fulfilled')
}, function (error) {
  console.log('Some promise rejected: ' + error.message)
})
2022-08-19