また自分の理解したことのメモです。
JavaScriptの非同期処理に関して、主にPromise
とasync
/await
について理解したことをまとめたいと思います。
##非同期処理
同期処理とは、簡単に説明すると処理が上から順番に行われていくことです。
console.log(1);
console.log(2);
console.log(3);
1
2
3
これに対し、非同期処理とは1つの処理が終わるのを待たずに次の処理が行われることです。例として非同期関数であるsetTimeout()
を使用してみます。
console.log(1);
setTimeout(function(){
console.log(2)
},100);
console.log(3);
1
3
2
このようにsetTimeout()
の処理を待たずにあとの処理が先に行われました。これはサーバーとの通信などで時間のかかる処理によって、プログラム全体が止まってしまわないようにするために使われます。
##Promise
Promise
とは非同期処理の状態を表すオブジェクトです。Promiseには以下の3つの状態があります。
・pending
: 処理が実行中
・fulfilled
: 処理が成功
・rejected
: 処理が失敗
Promise
の処理が終了した後に、結果を利用するにはPromise
のメソッドであるthen()
とcatch()
を用います。
・then()
: Promise
の状態がfulfilled
のとき実行される処理
・catch()
: Promise
の状態がrejected
のとき実行される処理
以下のような例で具体的に説明します。
//Promiseオブジェクトを返す関数を定義
function time(sec){
return new Promise(function(resolve,reject){
setTimeout(function(){
//100より小さいと成功(fulfilledの状態を返す)
if(sec <= 100){
resolve();
}
//それ以上では失敗(rejectedの状態を返す)
else{
reject();
}
},sec)
})
};
console.log(1);
time(100)
.then(function(){console.log('success')})
.catch(function(){console.log('error')})
time(1000)
.then(function(){console.log('success')})
.catch(function(){console.log('error')})
console.log(2);
1
2
success
error
Promise
オブジェクトを返す関数として戻り値がnew Promise
となる関数を定義します。resolve()
,reject()
はそれぞれ処理が完了した時、失敗したときに呼び出されます。time(100)
のときはPromise
の状態がfulfilled
で返されるため、then()
の中の処理が行われ、一方、time(1000)
のときはPromise
の状態がrejected
で返されるため、catch()
の中の処理が行われます。
また、then()
メソッドは戻り値としてPromise
オブジェクトを返すため、連続して書くことができます。この時途中でエラーが起きると処理が飛ばされcatch()
が呼び出されます。
time(100)
.then(function(){console.log(1)})
.then(function(){console.log(2)})
.then(function(){console.log(3)})
.catch(function(){console.log('error')})
console.log(4)
4
1
2
3
##async
/await
async
/await
を用いた非同期処理の構文について説明します。async
とは関数の前に宣言することで、非同期関数を定義することができます。
//非同期関数の宣言
async function sample() {}
非同期関数は戻り値として、Promise
オブジェクトを返します。関数の処理が実行され、値を返すと戻り値をresolve
が呼び出され、何らかのエラーなどが起こるとreject
が呼び出されます。
async
で定義した非同期関数の中ではawait
という演算子が使用できます。await
を関数の前に指定すると、その関数のPromise
オブジェクトが結果を返すまでその後の処理が待機します。
//awaitを用いない時
async function sample1(){
time(100)
.then(function(){console.log(1)})
console.log(2);
}
//awaitを用いた時
async function sample2(){
await time(100)
.then(function(){console.log(1)})
console.log(2);
}
sample1();
sample2();
2
1
1
2
await
を用いない場合、関数の中の非同期処理より先にあとの処理が実行されますが、await
を用いると指定した関数の処理が終了するまであとの処理が行われません。
非同期処理を同期的に処理したい場合、Promise
のthen()
メソッドを用いるよりも、async
/await
を用いるほうが簡潔な記述でかけることが多いです。
##まとめ
JavaScriptの非同期処理に関することとして、Promise
とasync
/await
についてまとめてみました。async
/await
を用いると記述が簡潔になりますが、新しい規格のため対応していないこともあるので注意が必要です。
##参考記事
[【JavaScript】Promise で非同期処理を記述するー株式会社ライトコードー]
(https://rightcode.co.jp/blog/information-technology/javascript-promise)
JavaScriptと非同期処理の話
[async/await 入門(JavaScript)]
(https://qiita.com/soarflat/items/1a9613e023200bbebcb3#resolve%E3%81%99%E3%82%8B)