非同期処理とは
ある処理が完了する前に、次の処理を開始することができる仕組みのことです。通信が発生する処理(WebAPIを叩く・DBへクエリを投げるなど)で発生します。実行処理を待たずに、並行して次の処理を実行するので、待ち時間の無くプログラムを実現することができます。
一方、同期処理は、ある処理が完了するまで、次の処理を開始することができません。そのため、処理が完了するまで待たなければならず、プログラムの実行速度が低下する可能性があります。
図に表しました。非同期処理では、タスクAがずっと動いています。
非同期処理のメリット
ユーザーを待たせない: 重い処理や時間のかかる通信中でもユーザーは別の操作ができる(便利・離脱を防ぐ)
非同期処理のデメリット
制御が難しい: 例えば、APIを叩くと非同期処理になりますが、これが長い。実行完了までに次の処理に行ってしまうとエラーになる。「実行完了までデータが存在しない」状態になる。
対処法
Promiseを使って非同期処理の実行完了を制御する。このPromiseには3つの状態があります。
pending: 初期状態
fulfilled: 処理が成功して完了した状態
rejected: 処理が失敗して完了した状態
基本的な記述は以下です。
const promiseFunc = () => {
return new Promise((resolve, reject) => {
someAsynchronousFunc(() => {
// 非同期処理
}).then(() => {
resolve('成功') // 非同期処理が成功した場合
}).catch(() => {
reject('失敗') // 非同期処理が失敗した場合
})
})
}
この場合、.thenのresolve('成功')に到達するまでpromiseFuncが次の処理に進まないようになります(失敗したらreject('失敗'))。これで、デメリットである「制御が難しい」を解決しています。
なお、Promiseそのものは非同期処理の状態を管理する役目しかありません。このPromiseを使った構文は、もっと簡潔に書くことができます(シンタックスシュガー)
async/await
asyncとawaitを利用した、非同期処理の構文のことです。Promiseに比べて記述がシンプルで、直感的にわかりやすいものになります。
使い方
・非同期処理を伴う関数定義にasync を付ける
・非同期処理を伴う関数実行時にawait を付ける
・awaitはasync付き関数内でしか使用できない
const asyncAwaitFunc = async() => {
const hoge = await someAsychronousFunc(() => {
// 非同期処理
}).then(() => {
return '成功' // 非同期処理が成功した場合
}).catch(() => {
return '失敗' // 非同期処理が失敗した場合
})
return hoge
}
参考
とてもわかりやすかったです!!