LoginSignup
10
9

More than 5 years have passed since last update.

JavascriptでPromiseを使って非同期処理を逐次実行する方法

Last updated at Posted at 2017-06-26

概要

タイトルの通り。

Javascriptで配列に詰めたパラメータを1つずつ、ajaxなどの非同期処理を含む関数に渡して実行する場合
なにもしないと並列(配列に入ってる分、ajax関数が同時実行)で実行されます。

サーバ負荷などの考慮で、これを並列でなく逐次(同時に実行する処理が1つずつだけ)にする方法です。

es2016 とかであれば async await を使うと簡単です。

今回はあえてPromiseを使う方法の紹介です。

aws Lambda のnodeを使っていたらasync と arrow Functionの組み合わせで
文法エラーになってしまっていたのでPromiseを引っ張り出してきました。
調べたらnode7.6からasyncとawaitが標準でサポートされた模様

例1

配列分、thenの連鎖を作っておく方法

@mpyw さんにコメント頂いた方法
すっきり書けるのでこっちの方が好みです。ありがとうございます。

const resolveAfter = (args) => {
  return new Promise((resolve) => {
    console.log(args);
    setTimeout(resolve, 1000);
  });
};

const argsList = [
  { id: 1, name: 'taro' },
  { id: 2, name: 'jiro' },
  { id: 3, name: 'saburo' }
];

let p = Promise.resolve();

argsList.forEach((args) => {
  p = p.then(() => resolveAfter(args));
});


イメージとしては
* 非同期処理を含む関数(でPromiseされてないもの)はPromiseで括る
* パラメタを配列に入れ、forEach等で回す(処理順を確保)
* 再代入するpを定義、pに配列分非同期処理のthenの連鎖を詰める感じ

例2

reduceを使う方法
letはちょっと・・・な人はこちら

argsList.reduce((current, args) => {
  return current.then(() => {
    return resolveAfter(args);
  });
}, Promise.resolve());

イメージとしては

  • 非同期処理を含む関数(でPromiseされてないもの)はPromiseで括る
  • パラメタを配列に入れ、reduceで回す(処理順を確保)
  • reduceのinitialに Promise.resolve() を入れることでPromiseObjectが入る
    • これによりreduceのiterateの都度、Promise.thenされるようになる
    • reduceを使うことで1つ前のpromiseオブジェクトを取得できるのでそれを利用した方法
10
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9