JavaScriptのPromiseについて復習のためにまとめてみる

今回はそこそこ使うものの曖昧な理解でいたJavaScriptのPromiseについてまとめてみます。

まず例として下のような処理を考えてみます。

const func1 = () => setTimeout(() => console.log('func1'),1000);
const func2 = () => setTimeout(() => console.log('func2'),500);
const func3 = () => setTimeout(() => console.log('func3'),1000);
const func4 = () => setTimeout(() => console.log('func4'),500);
func1();
func2();
func3();
func4();

まずブラウザのコンソールで実行してみます。期待する処理としては 1秒後にfunc1が出力、その0.5秒後 func2が出力、その1秒後にfunc3が出力、そしてその0.5秒後ににfunc4が出力されるというもの

結果①

しかし実際には下記のような結果となりました。。(func2,func4,func1,func3の順に出力)

理由としてはsetTimeout関数の非同期処理(ある処理の実行の終了を待たず処理を実行する)の性質のためです。

これを解消するために下記のようなコードに書き換えてみます。

const funcAll = () => setTimeout(() => {
  console.log('func
  setTimeout(() => 
    console.log('func2');
    setTimeout(() => {
      console.log('func3');
      setTimeout(() => {
        console.log('func4');
      },500)
    },1000)
  },500)
},1000);
    
funcAll();

 

結果②

結果は下記のようになりました。

意図した通りに動くようにはなったものの、callback関数のネスト構造によって大変読みにくいコードになってしまっています。

これを解消するためにPromiseで上記のコードを書き換えてみます。(今度は表示されるのにかかった秒数も出力してみます)

 const customFunc = (num,delaySecond,countSecond) => {
        return new Promise ((resolve, reject) => {
            setTimeout(() => {
                console.log('func' + num + ' : ' + (countSecond + delaySecond) + 'ms');
                resolve(countSecond + delaySecond);
            }, delaySecond);
        });
    }

   
    Promise.resolve()
        .then(() => customFunc(1,1000,0))
        .then((totalSecond) => customFunc(2,500,totalSecond))
        .then((totalSecond) => customFunc(3,1000,totalSecond))
        .then((totalSecond) => customFunc(4,500,totalSecond))
        .finally(() => {
            console.log('completed!!');
        })           

 

最終結果

実行結果がこちら

期待通りの処理になりました。コールバック関数のネスト構造も解消されています。

以下要点だけ解説

Promiseで非同期処理が正常に実行されるとresolveが実行されます。resolveの引数に渡された変数(上のコードの例だとcountSecond + delaySecond の部分)はメソッドチェーンになっている場合はthenの引数(上の場合だとtotalSecondの部分)に入ります。最後に実行したい処理がある場合はメソッドチェーンの最後でfinallyを使って処理を実行できます。

ちょっと説明不足感はありますが、今日はここまでにしておきます。

次は async,awaitなども含めてもう少し掘り下げた記事を書く予定です(もっと勉強します。。)

 

Related article

おすすめ関連記事