定義
asyncとawaitは、時間のかかる処理(非同期処理)を扱うとき、入り組んだコードではなく、上から順に実行される文章のように読みやすく書けるようにするプログラミングの文法です。処理が終わるまでプログラム全体を止めることなく、結果を受け取る順番も自然に整理してくれます。
呼び出しベルを握って待つカフェの注文
カフェで飲み物を注文したあと、店員が作り終えるまでカウンターの前でぼんやり立ち続けたらどうなるでしょう。後ろに並んだほかのお客さんは注文すらできず、お店全体が止まってしまいますよね。コンピューターのプログラムも同じです。遠くのサーバーから大きな写真をダウンロードしたり、データを取ってきたりする作業は、思った以上に時間がかかります。もしデータが届くまでコンピューターがすべての動作を止めたら、画面は真っ白に固まってしまいます。
そこでコンピューターは、時間のかかる作業をどこかに預けて、すぐに別の仕事をどんどん片づけます。これを「非同期処理」と呼びます。呼び出しベルを手に席へ戻り、スマホを見ながら時間を有効に使うのと同じです。ただ、従来の方法では「ダウンロードが終わったらAをして、Aが終わったらBをして、Bが終わったらCをして」という指示を、数珠つなぎに書かなければなりませんでした。
そうするとコードがどんどん右へ押し出され、読みづらい階段のような形になってしまいました。開発者はこれを「コールバック地獄」と呼びました。asyncとawaitは、この散らかって絡まったコードを1行ずつ上から下へすっきり読める形に整えてくれる道具です。
asyncとawaitの見事な役割分担
この2つの言葉は、ふつうセットで使います。awaitは、基本的にasyncが付いた関数の中で使う言葉です。まず関数名の前に付けるasync(エイシンク)は、「この関数の中には、時間がかかって待たなければならない処理があります」とコンピューターにあらかじめ知らせる案内板です。この言葉が付いた関数は、結果を未来に渡してくれる特別な箱に入れて返します。
関数の中で実際に待つ必要があるコードの前には、await(アウェイト)を付けます。これは「この処理の結果が出るまで、この場所で少しだけ待ってね」という一時停止の合図です。サーバーから天気の情報をすべて受け取るまで、次の行へ進まずに落ち着いて待つわけです。
ここでいちばん大切なのは、その関数の中で順番を待つだけで、プログラム全体の画面やほかの作業はまったく止まらないということです。お客さんが席で友だちとおしゃべりしていても、コーヒーは厨房で勝手に作られていくように、コンピューターは画面をなめらかに保ったまま、バックグラウンドでデータをしっかり受け取ります。ただし、関数の中で重い計算を自分で長時間行うと、その間は画面が止まることがあります。
もう少し正確に言うと:構文糖衣の魔法
もう少し正確に言うと、asyncとawaitは、コンピューターの動作原理をまるごと変えた、まったく新しい技術ではありません。JavaScriptなどの言語で非同期処理を扱うために以前から使われてきたPromise(プロミス、将来値を渡すと約束するオブジェクト)という仕組みを、人間が読みやすいように包んだ外側の殻に近いものです。
プログラミングの世界では、このように動作は同じでも、人間が読み書きしやすいよう整えた文法を「シンタックスシュガー(構文糖衣)」と呼びます。コンピューターの内部では、今も複雑な非同期のルールに従って約束の箱をやり取りしていますが、書いている開発者の目には順番どおりに実行される普通のコードのように見えるようにしてくれるのです。
この直感的な構造のおかげで、エラーの捕まえ方もぐっと簡単になりました。普段のプログラミングで使う一般的な例外処理の文法(try-catch)をそのまま使えるので、インターネット接続が切れたりサーバーに問題が起きたりしたとき、どこでエラーが出たのかを簡単に見つけて対処できるようになりました。
よくある誤解
awaitを使うとプログラム全体が止まって、ユーザーはボタンも押せなくなる。
awaitは、その非同期関数の内部で次の行の実行を少し待たせるだけです。待っている間も、ウェブブラウザの画面描画やユーザーのマウスクリックなど、ほかの部分は止まらずに動きます。
async/awaitは、Promise(プロミス)を使わないために作られた代替手段だ。
JavaScriptのasync/awaitは、内部では今もPromiseをもとに動いています。Promiseのコードを人間が読みやすい形で表現してくれる、文法上の包み紙(構文糖衣)にすぎません。
日常で出会う場面
ショッピングアプリで、商品一覧をサーバーからすべて受け取るまで待ってから画面に表示するときに使います。
ログインボタンを押したとき、IDとパスワードが合っているかサーバーの応答を確認して次の画面に進めるときに使います。
つまり ひとことで
時間のかかる非同期処理を、人間が読みやすい順番で書けるようにするプログラミングの文法です。