その他

【JavaScript】非同期処理(Promise)

今回は僕を含めて鬼門だと感じたJavaScriptの非同期処理について書いていきたいと思います。
なお、この記事は『りあクト! TypeScriptで始めるつらくないReact開発』の書籍で学習した内容をアウトプットさせていただいています。めちゃくちゃいい本なので、ぜひ買ってみてください!

非同期処理とは

そもそも非同期処理とは何なのでしょうか。非同期処理は以下のような特徴を持っています。

  1. 通信が発生する処理で起きる

    Web APIを叩く
    データベースへクエリを投げるなど
  2. 実行完了を待たない
  3. 並行して次の処理を実行

非同期処理の扱いについて

非同期処理は便利な反面、扱いが難しいです。便利な点としては、実行完了を待たないので、重い処理や時間のかかる通信中にユーザは他の操作をすることができます。

一方で、実行完了までデータが存在しないので、そのデータを使って処理を書くとエラーになるといったケースがでてきます。それを防ぐため、非同期処理の実行完了を制御するということが必要なケースが多いです。

Promiseオブジェクトを作成してみる

では、Promiseオブジェクトを実際に作成してみて、挙動を詳しく見ていきます。

const isSucceeded = true;

const promise = new Promise((resolve, reject) => {
  if (isSucceeded) {
    resolve('Success');
  } else {
    reject(new Error('Failure'));
  }
});

promise.then((value) => {
    console.log('1.', value);

    return 'Succees again';
  })
  .then((value) => {
    console.log('2.', value);
  })
  .catch((error) => {
    console.error('3.', error);
  })
  .finally(() => {
    console.log('4.', 'Completed');
  });
$ node promise.js 
1. Success
2. Succees again
4. Completed

Promiseのコンストラクタに渡しているのがresolveとrejectの関数になります。中身としては、isSucceededがtrueならresolveを実行し、falseならrefectを実行するという単純なものです。

promiseの状態

promiseは次の3つの状態を持っています。

  • pending : 初期状態
  • fulfilled : 処理が成功して完了した状態
  • rejected : 処理が失敗して完了した状態

これがとても重要なので、これを踏まえて上のコードを見ていきます。

11行目のpromiseからメソッドチェーンでthen((value) ~ と続いています。このthenが実行されるのが、promiseの状態がfulfilledのときです。また、このときvalueとして引数に渡されるのが、5行目のresolveメソッドの引数で渡されている’Success’です。

一方、catch((error) ~と続く箇所が実行されるのが、promiseの状態がrejectedのときです。また、このとき引数に渡されるのも同様に、7行目のrejectメソッドの引数として渡されているnew Error(‘Failure’)になります。

そして、最後に直前のthenやcatchが実行されるのを待って、finally(() ~ が実行されます。

thenのネスト

もちろん、thenはネストさせることもできます。

// 略
promise.then((value) => {
    console.log('1.', value);
    return 'Succees again';
  })
  .then((value) => {
    console.log('2.', value);
    return value
  })
  .then((value) => {
    console.log('2回目のthen', value);
    return value
  })
  .then((value) =>{
    console.log('3回目のthen', value);
  })
// 略
$ node promise.js 
1. Success
2. Succees again
2回目のthen Succees again
3回目のthen Succees again
4. Completed

さいごに

少し長くなってきたので、今回はここで区切りたいと思います。Promiseについて分かったけどちょっと見にくいと思った方もいるかと思います。次はこのPromiseをいい感じに書くことができるasync awaitについてまとめていきたいと思います。

ここまで読んでいただきありがとうございました。

ABOUT ME
酒井 駿
名古屋工業大学大学院卒業後、豊田合成(株)で品質管理を経験し、その後スタートアップ・マネーフォワードを経て、2024年11月に株式会社EGGHEAD創業。 製造業とエンジニアリング、両方の現場の知見を活かし、製造業における生成AIを活用した業務改善やシステム開発を支援します。