【JavaScript】非同期処理と async/await をある程度理解する
【実践したいこと】
細かい事までわかろうとするとキリがないのでそこまで深掘りしないとしても、async/await をよくわからないまま何となく使う状況からは脱却したい。
ここでは async/await についてすべて解説しているのではなく、自分が実際に async/await を使うときにはっきりさせたかった部分だけが書かれている。
【前提知識】
Promise
非同期処理とは
非同期処理とは、コード内の他の部分の処理を止めず (待たせず) に行われる処理のことである。
JavaScript は基本的にコードの上から順番に処理を完了させながら進むものであり、その中に時間のかかる処理が含まれているとそれが完了するまで次に進むことができない。
非同期処理は、この問題を解決するために使われる。
例えば以下のような機能について、非同期処理は適している。
HTTPリクエストによってデータを呼び出す
ファイルを読み込む
ユーザのカメラやマイクにアクセスする
async/await とは
async
/await
は、関数・メソッド単位で非同期処理を行いたいときにペアで使われる。
async
関数の前に付け、その関数が非同期処理を行うものであることを定義する。
このマーカーが付いた関数は、return
によって何らかの値を返すように書かれているとしても、必ず Promise オブジェクトを返す。
Promise オブジェクトとは、非同期処理の完了または失敗を表す。
await
async
がついた関数の中でだけ使うことができる。
async 関数の中で、Promise オブジェクトそのものや、Promise オブジェクトを返す他の関数やメソッドの前に付ける。
await
が Promise オブジェクトにつくと、その Promise を解決 (resolve) させた値をそのまま使えるようになる。
また、その Promise が解決または失敗するまで、 async 関数の他の処理は停止される。
await が待たせるのは、それが入っている async 関数の内部だけであり、async 関数と並行する他の関数の動きは止めない。
例として、以下のコードで説明する。
const functionA = async (url) => { const response = await window.fetch(url); const arrayBuffer = await response.arrayBuffer(); } functionA('./audio.wav');
メソッド window.fetch()
は、Promise オブジェクトを返す。
この処理が完了するまで、関数 functionA()
の中の次の処理には移らない。
メソッド window.fetch()
指定された URL やパスの場所にあるデータを取得する (対象のサーバにリクエストを送る)。
データが正しくあるという返答 (サーバからのレスポンス) が得られたら、そのレスポンスによって解決される Promise を返す。
window.fetch()
の処理が成功すると、指定した URL のレスポンスによって解決された Promise が返ってくる。
そこに await
がついているので、変数 response
に格納されるのは Promise オブジェクトではなく、その Promise を解決させたものであるレスポンスのほうになる。
続くメソッド arrayBuffer()
も、Promise を返す。
メソッド Response.arrayBuffer()
サーバからのレスポンスによって得られたファイルなどのデータを、バイナリデータの塊である ArrayBuffer オブジェクトとして表す。
ArrayBuffer としてのデータがすべて準備できたら、その ArrayBuffer オブジェクトによって解決される Promise を返す。
これにも await
がついているので、変数 arrayBuffer
には Promise オブジェクトではなく、レスポンスデータをバイナリデータにした ArrayBuffer オブジェクトが格納される。