web-dev-qa-db-ja.com

ブルーバードmapSeries

私は一連の約束を順番に実行しようとしていますが、前の約束が解決された後にのみ次の約束に進みます。 Bluebirdのドキュメントから:

イテレータは、前のアイテムまでアイテムに対して呼び出されず、そのアイテムに対してイテレータによって返される約束が実行されます。 http://bluebirdjs.com/docs/api/promise.mapseries.html

var Promise = require('bluebird');


function test(time) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log(time);
            resolve(time);
        }, time);
    });
}

Promise.mapSeries([test(2000), test(1000), test(500), test(3000)], function(a) {
    return a;
}).then(function(results) {
    console.log(results);
});

私が期待しているのは、テスト関数内のconsole.logが、2000、1000、500、3000の順に表示されることです。ドキュメントに記載されているように、各アイテムは前のアイテムが解決された後にのみ実行されるため、私は期待しています。代わりに、500、1000、2000、3000を取得します。これは、すべての関数が瞬時に呼び出されることを反映しています。さらに、結果には、呼び出された順序で結果が表示されますが、現時点では関係ありません。

私はここで何かを誤解していますか?

8
yBrodsky

テスト呼び出しは、Promise.mapSeriesが実行される前に行われます。また、mapSeriesは通常promiseインスタンスで実行されます。たぶん、次の例は理解するのに役立ちますか? test(time)今回は関数を返す方法に注意してください。

function test(time) {
    return function(value) {
      return new Promise(function(resolve, reject) {
          setTimeout(function() {
              console.log('time', time);
              resolve(time);
          }, time);
      });
    };
}

Promise.resolve([test(2000), test(400), test(1000), test(1), test(5000)])
       .mapSeries(function(asyncMethodPassed) {
                    return asyncMethodPassed();
}).then(function(results) {
    console.log('result', results);
});
11
Ben Dadsetan