今回は僕を含めて鬼門だと感じたJavaScriptの非同期処理について書いていきたいと思います。
なお、この記事は『りあクト! TypeScriptで始めるつらくないReact開発』の書籍で学習した内容をアウトプットさせていただいています。めちゃくちゃいい本なので、ぜひ買ってみてください!
非同期処理とは
そもそも非同期処理とは何なのでしょうか。非同期処理は以下のような特徴を持っています。
- 通信が発生する処理で起きる
Web APIを叩く
データベースへクエリを投げるなど - 実行完了を待たない
- 並行して次の処理を実行
非同期処理の扱いについて
非同期処理は便利な反面、扱いが難しいです。便利な点としては、実行完了を待たないので、重い処理や時間のかかる通信中にユーザは他の操作をすることができます。
一方で、実行完了までデータが存在しないので、そのデータを使って処理を書くとエラーになるといったケースがでてきます。それを防ぐため、非同期処理の実行完了を制御するということが必要なケースが多いです。
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についてまとめていきたいと思います。
ここまで読んでいただきありがとうございました。