@ledsun blog

無味の味は佳境に入らざればすなわち知れず

reduceでPromiseをつないでタイムライン実行する

Promiseとreduceを組み合わせたトリック。 適当な間を置いてイベント発行するstubを作る時に使いました。

指定時間後に処理を実行するPromiseを作ります。

var DelayPromise = function(delay, action) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      try {
        action();
        resolve();
      } catch (err) {
        reject(err);
      }
    }, delay);
  });
};

map/reduceでつなげて実行します。

[1, 2, 3].map(function(record) {
    // Promiseはnewすると実行します。前のPromise完了後に実行する関数を作ります。
    return function() {
      // 指定秒後に数字を表示します。
      return new DelayPromise(record * 1000, function() {
        console.log(record)
      });
    }
  })
  .reduce(function(prev, action) {
    // 順次実行するために各actionをthenで繋ぎます。
    return prev.then(action);
  }, Promise.resolve())
  .catch(function(err) {
    console.error(err, err.stack);
  });

1秒後に1が、それから2秒後に2が、それから3秒経って3が表示されます。