情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsで複数のプロミスの中で最初に完了したものを取得する

複数のプロミスの中で最初に完了したものを取得するにはプロミスクラスのany関数を使用します。

any関数は下のプロミスクラスで提供されています(ただし、whenモジュールの場合、when.any関数となります)。

  • bluebirdクラス
  • when.promiseクラス
var bluebird = require('bluebird');

var p = bluebird.any([p1, p2, 'xxx']);

第1引数に複数のプロミスを配列として指定します。あるいは、配列以外のイテラブルとして指定することもできます。

あるいは、プロミスを指定する代わりに任意の値を指定することもできます。この場合、プロミスクラスのresolve関数によりこの値を結果とする完了状態のプロミスが作成されます。

返り値として最初に完了したプロミスが得られます。

ただし、全てのプロミスが保留状態からエラー状態に変わった場合にはエラー状態のプロミスが返ります。

サンプルコード1

bluebird-any-1.js

var bluebird = require('bluebird');

var p1 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        resolve('p1');
    }, 3000);
});
var p2 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        resolve('p2');
    }, 1000);
});
var p3 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        resolve('p3');
    }, 5000);
});
var p4 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        reject(new Error('p4'));
    }, 500);
});

bluebird.any([p1, p2, p3, p4]).done(function (r) {
    console.log(r);
}, function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

  • Bluebird
    npm install bluebirdでインストールします。

実行結果

C:\work\node>node bluebird-any-1.js
p2

サンプルコード2

bluebird-any-2.js

var bluebird = require('bluebird');

var p1 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        reject(new Error('p1'));
    }, 3000);
});
var p2 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        reject(new Error('p2'));
    }, 1000);
});
var p3 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        reject(new Error('p3'));
    }, 5000);
});
var p4 = new bluebird(function (resolve, reject) {
    setTimeout(function () {
        reject(new Error('p4'));
    }, 500);
});

bluebird.any([p1, p2, p3, p4]).done(function (r) {
    console.log(r);
}, function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

  • Bluebird
    npm install bluebirdでインストールします。

実行結果

C:\work\node>node bluebird-any-2.js
{ AggregateError: aggregate error
    at SomePromiseArray._checkOutcome (C:\work\node\node_modules\bluebird\js\release\some.js:82:17)
    at SomePromiseArray._promiseRejected (C:\work\node\node_modules\bluebird\js\release\some.js:69:17)
    at Promise._settlePromise (C:\work\node\node_modules\bluebird\js\release\promise.js:568:26)
    at Promise._settlePromise0 (C:\work\node\node_modules\bluebird\js\release\promise.js:606:10)
    at Promise._settlePromises (C:\work\node\node_modules\bluebird\js\release\promise.js:681:18)
    at Async._drainQueue (C:\work\node\node_modules\bluebird\js\release\async.js:138:16)
    at Async._drainQueues (C:\work\node\node_modules\bluebird\js\release\async.js:148:10)
    at Immediate.Async.drainQueues [as _onImmediate] (C:\work\node\node_modules\bluebird\js\release\async.js:17:14)
    at tryOnImmediate (timers.js:543:15)
    at processImmediate [as _immediateCallback] (timers.js:523:5)
  '0':
   Error: p4
       at Timeout._onTimeout (C:\work\node\promise-any-2.js:20:10)
       at tryOnTimeout (timers.js:224:11)
       at Timer.listOnTimeout (timers.js:198:5),
  '1':
   Error: p2
       at Timeout._onTimeout (C:\work\node\promise-any-2.js:10:10)
       at tryOnTimeout (timers.js:224:11)
       at Timer.listOnTimeout (timers.js:198:5),
  '2':
   Error: p1
       at Timeout._onTimeout (C:\work\node\promise-any-2.js:5:10)
       at tryOnTimeout (timers.js:224:11)
       at Timer.listOnTimeout (timers.js:198:5),
  '3':
   Error: p3
       at Timeout._onTimeout (C:\work\node\promise-any-2.js:15:10)
       at tryOnTimeout (timers.js:224:11)
       at Timer.listOnTimeout (timers.js:198:5),
  length: 4 }

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js