初心者にも分かりやすいasync/awaitの機能の説明(JavaScript)
JavaScriptでプログラムを書いていると、async/awaitという、なんだか分かったような分からないような文法に出会うことがありますよね。
「asyncは非同期?な関数につける構文?」
「asyncって関数につけると、関数の中でawaitって使えるようになる?」
「awaitって書いた後に、async関数を実行すると、普通に動くようになる?」
なんだか少し難しい文法のように感じます。
この記事では、プログラミング初心者がJavaScriptを学ぶにあたって、少し難しいと感じる事の多い、async/awaitの機能の要点を分かりやすく説明いたします。
以下の流れで説明します。
1. 非同期処理って何?
async/awaitとは、JavaScriptで非同期処理を行う時に用いる構文です。
では、そもそも非同期処理とは何でしょうか?
非同期処理とは「待っている間に、他のことをできるようにする仕組み」の事です。
「待っている間に、他のことをできるようにする仕組み」とはどういう事か、
銀行に例えてみましょう。
銀行にAさんがお金を引き出しに来ました。
Aさんが、銀行の窓口で「1万円お金を引き出したい」と伝えると「お待ちください」と伝えられました。
そして、銀行の窓口では、次の人のお話を聞きます。
Aさんのお金の引き出しが終わるまで、窓口の人が何もできなくなるわけではありません。
Aさんのお金の引き出しが終わるまでの間も、窓口の人は次のお客様の対応ができます。
すなわち、銀行の窓口は「待っている間に、他のことをできる」のです。
これは当たり前のことのように思えます。
しかし、実はプログラムで考えてみると、ちょっと難しいことなのです。
お金の引き出しを行う関数 hikidashi があったとします。
この関数 hikidashi を呼び出してしまうと、その実行が終わるまで、
次の行に進めません。
function hikidashi(){
return 10000;
}
console.log('お金を引き出します');
const result = hikidashi();
console.log(result);
console.log('次のお客様に対応します');こちらのプログラムの実行結果は次の通りです。
お金を引き出します
10000
次のお客様に対応します先に10,000円引き出す処理が実行されてしまいました。
このように処理が行われる仕組みを、同期処理と呼びます。
一方で、プログラムでも今回の引き出し処理の例のように「待っている間に、他のことをできる」ようであって欲しい事は多々あります。
例えば、SNSで全ての投稿の画像がダウンロードされて表示されるまで、アプリが止まってしまったら凄く不便です。
また、ゲームのアプリで、CPUのキャラクターが動いている間、自分のキャラクターが動けないようであれば、多くのゲームは成立しません。
このような問題を解決し、「待っている間に、他のことをできるようにする仕組み」が非同期処理です。
2. asyncを関数につけると?
それでは、JavaScriptで非同期処理を実現するには、どのようにすればよいでしょうか?
その1つの方法にasync/awaitがあります。
(エーシンク/アウェイトと読みます)
ここでは、asyncの機能について説明していきます。
asyncは関数の宣言の前につけます。
asyncがつけられた関数は非同期に処理されるようになります。
先ほどのhikidashi関数にasyncをつけてみましょう。
async function hikidashi(){ return 10000; } console.log('お金を引き出します'); const result = hikidashi(); console.log(result); console.log('次のお客様に対応します');
このプログラムの実行結果は次の通りです。
お金を引き出します
Promise {<fulfilled>: 10000} ※
次のお客様に対応します※2行目の表示内容は実行環境によって異なります。
以下のように書き換える事で、取り出す事ができます。
async function hikidashi(){
return 10000;
}
console.log('お金を引き出します');
hikidashi().then((result)=>console.log(result));
console.log('次のお客様に対応します');このプログラムの実行結果は次の通りです。
お金を引き出します
次のお客様に対応します
10000このように、プログラムを記述した順番とは違う順番で出力されました。
hikidashi()の後のthen((result)=>console.log(result))はhikidashi()の処理が終わったら、console.log(result)を実行することを意味します。
これによって、先に「次のお客様への対応」を実行して、その後に10,000円を表示するプログラムを実現できました。
asyncを付けた関数によって非同期処理を実現できたのです。
3. awaitをつけて関数を実行すると?
それでは、awaitはどのような機能なのでしょうか?
さきほど、asyncを付けた関数の実行結果は、Promiseというオブジェクトが返されることが分かりました。
そして、その処理結果を取得するために、thenというメソッドを呼び出しました。
しかし、一方で、asyncがついている関数を今回だけは同期的に呼び出したい場合、つまり、呼び出し結果が得られるまで次の処理を実行したくない場合は、どうしたら良いのでしょうか。
このような時には、awaitを使うと次のように書けます。
async function hikidashi(){
return 10000;
}
console.log('お金を引き出します');
let result = await hikidashi();
console.log(result);
console.log('次のお客様に対応します');hikidashi関数の呼び出しの前にawaitを書き加えただけの、非常にシンプルな記述です。
このプログラムの実行結果は、次の通りです。
お金を引き出します
10000
次のお客様に対応しますawaitをつけたことによって、resultにはPromiseオブジェクトではなく、直接10,000が格納されるようになりました。
このように、awaitによって、シンプルな記述で、非同期関数を同期的に実行できます。
4. まとめ
本記事では以下の内容について紹介してきました。
- 非同期処理とは「待っている間に、他のことをできるようにする仕組み」
- JavaScriptでは、asyncを用いて非同期処理を実現可能
- awaitは、asyncをつけた関数を同期的に実行できるようにするもの
説明は以上です。
カサレアルでは、JavaScriptを学ぶ方に向けて「JavaScriptで学ぶ初めてのプログラミング」や「モダンJavaScript入門」「JavaScript応用」などのコースを開催しています。
JavaScriptに関するコースの詳細や開催日程に関しては以下のリンクをご覧ください。
フロントエンド開発を学ぶ研修一覧
https://www.casareal.co.jp/ls/service/openseminar/search/frontend