JavaScript

【JavaScript】 async / await の使い方

投稿日:2019年2月4日 更新日:

本サイトの JavaScriptで一定時間待ってから処理を開始する方法 でも少し使ったのですが、JavaScript の async / await の使い方についてこちらのページにまとめておきます。

1. JavaScript の非同期処理とは?

たいていのプログラミング言語では、

foo() という関数を実行し、それが終了したら bar() という関数を実行する

という処理を書く場合、以下のように書きます。


foo();

bar();

「何当たり前のことを行っているんだ」と思われるかもしれませんが、JavaScript は少し違います。

JavaScript の面倒臭さ

JavaScriptの場合、foo() 関数の中で、「サーバーにアクセスする」や、「ファイルにアクセスする」といった「待ち」が発生する処理があった場合、さっさと次の bar() が実行され、foo() 内の残りの処理は後回しにされます(これが非同期という意味になります)。

待つ」という時間が無駄にならないので、プログラム全体から見れば効率がよいという見方もできますが、「○○○という処理が終了してから□□□という処理を開始したい」というよくある処理(同期処理)を書きたい場合に、先程のコード例のように自然な書き方ができないという面倒臭さがあるのです。

コールバックの時代

では、「JavaScript で同期処理(処理を順番に実行させる)を行う」場合にどうしていたかと言うと、初期の頃は「非同期処理を含んだ関数に コールバック関数を渡して、処理の最後に実行してもらう」というやり方をしていました。

しかしこのやり方だと、コールバック関数の増加に伴いとてつもなくコードが分かりづらくなります。階層が深くなったり、エラー処理が面倒になったりいいことがありません。

Promise をそのまま使う時代

その後、ECMAScript 6 (ES6) の仕様に Promise というオブジェクトが加わりました。これを使うと同期処理を書く場合に、コールバックをなくすことができます。

とはいえ、これではまだ「分かりやすいコードが書ける」と言うには微妙でした。

async/await の登場

そして、ECMAScript 2017 (ECMA-262) という仕様で「Async function」という機能(文法)が追加されました。これが今回の主題である「async / await」のことを指しています。

async / await というのは、Promise をより簡単に使うための文法であって、新しい機能ではありません。非同期処理が前より書きやすくなりましたが、ちゃんと理解するには依然として Promise についての理解が必要です。

お勧めページ: Async/await

2. async /await の使い方

async /await の基本的なコード例は以下です。

// 非同期処理を含み Promiseを返す関数
function foo() {
  return new Promise((resolve, reject) => {

    // 非同期処理(後述)
    // 処理終了箇所で resolve() を実行する、エラーなら reject() を実行する

  });
}

async function main() {
  try {
    
    await foo(); // 処理が終わるまで待ちます

    bar();

  } catch(err) {
    alert(err);
  }
}
main();

やっていることを以下にまとめます。

  1. 非同期処理を含み、Promise を返す関数を用意します。… foo()
  2. async を付けた関数を用意します。… main()
    • async を付けた関数内でないと、await が使えません。
  3. その関数内で、await を頭につけて foo() を実行させます。
    • これで、foo()が終了するまで処理が次に進まなくなります。
  4. foo() が終了した後で実行したい関数 bar() を記述します。

「非同期処理を含み、Promise を返す関数」というのは、例えば以下のような関数になります。

function foo() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000);
    //setTimeout(() => {reject(new Error("エラー!"))}, 1000);
  });
};

async / await の基本的な使い方は以上になります。

3. おわりに

JavaScript で「非同期処理 を 同期処理 にして使いたい」という要望があった場合、先程のコード例をベースにして考えると、意外と簡単に処理が書けるのではないでしょうか。(とはいえ、Promise は理解していた方がよいです)

参考

📂-JavaScript

執筆者:labo


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

JavaScript

JavaScriptで一定時間待ってから処理を開始する方法

目次1. はじめに2. 手順(async function版)3. 手順(Promise をそのまま使った版)4. いつ使うのか?参考 1. はじめに JavaScriptで一定時間待ってから何か処理 …

JavaScript

JSON.stringify() の引数に関する忘備録

JavaScript でよく使う JSON.stringify()メソッドですが、第二引数と第三引数の意味を忘れがちなので本ページに記録しておきます。

Web Security

JavaScript の alert は CPUにたいした負荷を掛けないしタブを閉じれば終了します

以下の話題について書きます。 不正プログラム書き込み疑い補導 03月04日 20時04分 クリックすると同じ画面が表示され、消えなくなる不正なプログラムのアドレスをインターネットの掲示板に書き込んだと …

JavaScript

JavaScript の静的インポートと動的インポート

目次1. JavaScript の 2種類のインポート機能(概要)1. モジュール側2. 呼び出し側静的インポート動的インポート2. 静的インポート1. この機能の呼び名2. 特徴3. 仕様4. ブラ …

JavaScript

Luminous を使ってみる

ウェブページ上の画像をポップアップ表示する JavaScript ライブラリである Luminous の使い方について説明します。