非同期処理とは
ある処理が完了する前に、次の処理を開始することができる仕組みのことです。通信が発生する処理(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
}
参考
とてもわかりやすかったです!!