Async and Await in Vanilla JavaScript
ここ数年、私は個人的なプロジェクトや本業でBlazor WebAssemblyを多く使用しています。
時々、特定の操作を実行するためにJavaScriptコードを呼び出す必要があります。
この場合、特定のJavaScriptフレームワークを使うことはないので、多くの機能はバニラJavaScriptで行わなければなりません。
JavaScriptで非同期コードを扱ったことがある人なら、コールバック、Promise、エラーを処理するのがどれほど難しいか、おそらくご存知でしょう。幸いなことに、asyncとawaitという、あなたの生活を楽にしてくれる構文上の特徴があります。
asyncとawaitは、非同期コードをより読みやすく簡潔に記述するためのキーワードです。これらはプロミスに基づくものですが、then()メソッドやcatch()メソッドの入れ子や連鎖を回避することができます。その代わりに、awaitキーワードを使用して、Promiseがresolveされるかrejectされるまで非同期関数の実行を一時停止させることができます。こうすることで、非同期コードをあたかも同期であるかのように書くことができます。
asyncとawaitの使い方
asyncとawaitを使うには、2つのことをする必要があります
関数名またはarrow関数の前にasyncキーワードを付けて、async関数を宣言する。
async関数内でawaitキーワードを使い、promiseのresolveやrejectを待ちます。
以下は、APIからデータを取得し、その結果をコンソールに記録する非同期関数の簡単な例です
code: JavaScript
async function fetchData() {
let data = await response.json();
console.log(data);
}
// Call the async function
fetchData();
非同期処理を実行しているにもかかわらず、コードが同期コードのように見えることに注目してください。awaitキーワードは、JavaScriptエンジンに、Promiseがresolveされるまで非同期関数の実行を一時停止させます。その後、Promiseのresolveされた値で実行が再開されます。
また、try...catchブロックを使って、同期コードと同じように非同期関数のエラーを処理することができます。例えば、以下のような感じです
code: JacaScript
async function fetchData() {
try {
let data = await response.json();
console.log(data);
} catch (error) {
// Handle the error
console.error(error);
}
}
asyncとawaitの長所
asyncとawaitを使用すると、コードの品質と可読性にいくつかの利点があります:
プロミスやコールバックを使用する際に発生する定型的なコードや字下げを減らすことができます。
実行の自然な流れに沿うため、コードがより直線的で直感的になります。
catch()メソッドや拒絶コールバックの代わりに標準的なtry...catchブロックを使用できるため、エラー処理が改善されます。
ブレークポイントを使用して、あたかも同期的であるかのようにコードをステップスルーできるため、コードのデバッグが容易になります。
asyncとawaitの欠点
asyncとawaitは非常に便利で強力な機能ですが、注意しなければならない点もあります:
awaitはasync関数の中でしか使えません。awaitは非同期関数の中でしか使えません。非同期関数の外で使おうとすると、シンタックスエラーが発生します。
非同期関数は、たとえ明示的にPromiseを返さなくても、常にPromiseを返します。つまり、非同期関数が返す値を取得するには、then()またはawaitを使用する必要があります。
awaitを使うと、現在の非同期関数の実行がブロックされますが、プログラム全体がブロックされるわけではありません。awaitに依存しない他の関数やイベントは、バックグラウンドで引き続き実行されます。
ループや並列タスクでawaitを使用することは避けるべきです。代わりに、Promise.all()やPromise.race()を使って、一度に複数のPromiseを待つようにする必要があります。
結論
Asyncやawaitは、コードの品質や可読性を向上させ、エラー処理やデバッグの経験値を高めることができます。ただし、非同期関数内でのみ使用する、戻り値を適切に処理する、ループや並列タスクでは使用しないなど、注意すべき点もあります。