1. ホーム
  2. javascript

[解決済み] ES6のPromise.all()を使用する際に、並行処理を制限する最善の方法は何でしょうか?

2022-05-05 22:38:47

質問

私は、データベースから照会されたリストを反復し、そのリストの各要素に対して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 */});

このコードはNode 4.3.2上で動作しています。 もう一度言いますが Promise.all は、常に一定の数の Promise が進行中であるように管理されるのですか?

どのように解決するのですか?

注意点 Promise.all() はプロミスが作業を開始するきっかけにはなりませんが、プロミスそのものを作成することはできます。

それを考えると、一つの解決策は、プロミスが解決されるたびに、新しいプロミスを開始すべきか、すでに限界に達しているかをチェックすることでしょう。

しかし、ここで車輪を再発明する必要はないでしょう。 この目的に使用できるライブラリの1つが es6-promise-pool . その例から。

// On the Web, leave out this line and use the script tag above instead. 
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)
})