JavaScript非同期処理さんぷる
という名のおぼえがき
間違えているかもしれない
Promiseとawait
説明
Promise内の処理は非同期で行われます。
同期させたい場合はasync関数とawaitを使います。
Promise
let flag = true;
const promise1 = new Promise( ( resolve, reject ) => {
if( flag ){
resolve( 'resolve(成功)です' );
}
else{
reject( 'reject(エラー)です' );
}
})
promise1.then( result => { // thenはresolveが返ってきた際に実行されます。
console.log( result ); // > resolve(成功)です
}) .catch( error => { // catchはrejectが返ってきた際に実行されます。
console.error( error ); // > reject(reject(エラー))です
}) .finally( () => { // finallyは結果の可否に関わらず実行されます。
console.log( '処理が完了しました' );
});
// この例では成功が返ってきます。
await
async function inuGohan(){ // functionの前にasyncと書くことでawaitが使えるようになるよ
promiseGohanShitaku(); // ごはんの支度をするよ
inu.eat(); // 支度中でも構わず食べようとするよ
await promiseGohanShitaku(); // 支度が終わるまで待っててね
inu.eat(); // 待てと言えばちゃんと待てる子です
}
試してみよう
checkboxがfalseの時にreject(エラー)、trueの時にresolve(成功)を返します。
コード
複数の処理を同時に行う
説明
Promiseを配列に入れることで、複数の処理を同時に行うことができます。
配列に入れたPromiseは以下のメソッドに配列を渡すことで実行できます。
- Promise.all()
- Promise.allSettled()
- Promise.any()
- Promise.race()
いすれも配列の先頭から実行していきますが、結果を受け取った時の挙動が異なります。
それぞれの特徴
- Promise.all
全てresolveであれば結果を配列にまとめて返します。
rejectされた場合はその時点でエラーを返し、他の結果は返しません。 - Promise.allSettled
すべての処理が終わった時に、各結果のオブジェクトを配列にまとめて返します。
[ { status: 'fulfilled', value: 'resolveの値' }, // 成功 { status: 'rejected', reason: 'rejectの値' } // エラー ] - Promise.any
最初に返ってきたresolveの値を返します。
全てrejectだった場合は、エラーメッセージを返します。 - Promise.race
最初に返ってきた結果を返します(可否は問わない)。
試してみよう
3つのPromiseを実行します。
2 → 1 → 3 の順で結果が返ってきます。
checkboxがfalseの時にreject(エラー)、trueの時にresolve(成功)を返します。
コード
プロミスチェーン
説明
Promiseの結果を受け取るthenメソッドは繋げていくことも可能です。
then()内でreturnされた値が次のthen()へ渡されます。
複数の非同期処理を順番に実行していきたい時に役に立ちますが、繋げすぎると可読性やパフォーマンスが低下するので、複雑な処理をしたい場合はasyncを使った方がいいかも。
thenが繋がるようす
new Promise( resolve => {
resolve( 'ほげほげ' );
} )
.then( result => {
return `${ result }ふがふが`; // returnされた値が次のthenへ
} )
.then( result => { // result == 'ほげほげふがふが'
return `${ result }ぴよぴよ`;
} )
.then( result => { // result == 'ほげほげふがふがぴよぴよ'
console.log( `${ result }おあー` ); // >ほげほげふがふがぴよぴよおあー
} );
試してみよう
トリ○ク2で出てきた必ず5になる計算。
1回の計算毎に計算用の関数を実行、returnをし、次のthenへ渡しています。
計算用の関数も非同期関数ですが、0.5秒のタイマーを入れてみたので、結果を待ってから実行しているのがよくわかると思います。
1~100の範囲を超えた数値を指定した場合、エラーとなります。
コード
async
説明
awaitの件で出てきたasyncくんです。
asyncはpromiseの糖衣構文で、awaitやtryを用いることで
- thenによる受け渡しをする必要がなくなり、普通の処理のように書ける
- 連鎖するPromiseをforなどでまとめて書くことができる
基本的な流れ
const async_kihon = async () => {
try{
new Promise( ( resolve, reject ) => {
reject( 'awaitを付けないとcatchされないので気をつけて' );
} );
for( let i = 0; i < 2; i++ ){
const result = await new Promise( ( resolve, reject ) => {
if( !i ){ // 1回目
resolve( 'resolveの場合、このまま先に進みます' );
}
else{ // 2回目
reject( 'rejectの場合、catchに飛びます' );
}
} );
console.log( result ); // この例では、2回目はrejectされているので実行されません
}
} catch( error ){
console.error( error );
};
}
試してみよう
配列の値を一つ一つ回し、セレクトボックスの値と比較します。
双方の値が合致したときにrejectします。