JavaScriptのasync/awaitの書き方

JavaScript

JavaScriptのasync/awaitの書き方についてまとめました。

JavaScriptのasync/await

async/awaitは、Promiseをさらに直感的に記述できるようにしたものです。
Promiseについては次の記事を参考にしてみてください。


asyncは、Promiseを返却する関数の宣言を行います。
asyncがあると、必ずPromiseが返されます。
awaitは、Promiseを返却する関数の非同期処理が完了するまでawaitの処理を待機することができます。
Promiseの書き方との違いを比較するために、まずはPromiseの文をみてみましょう。

Promiseで書いた例文

//Promiseで書いた場合
function time(val) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log(val++);
      resolve(val);
    }, 1000);
  });
}

time(0)
  .then(function (val) {
    return time(val);
  })
  .then(function (val) {
    return time(val);
  })
  .then(function (val) {
    return time(val);
  });

1秒ごとに0, 1, 2, 3と呼び出されます。
これをasync/awaitで書き直します。

async/awaitで書いた例文

// Async/Await
function time(val) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log(val++);
      resolve(val);
    }, 1000);
  });
}
async function init() {
 let val = await time(0);
 val = await time(val);
 val = await time(val);
 val = await time(val);
}
init();

コードがスッキリすることがわかります。

asyncキーワードを関数の前にセットします。
awaitを使うと、new Promiseで渡されたresolve(引数)の引数が渡されます。
awaitを付けないとnew Promiseのインスタンス(オブジェクト)が返されます。
そして、awaitをつけると、resolve()が呼ばれるまで待機状態となります。
awaitは必ずasyncの関数コンテキストで実行する必要があります。

let valに格納されている値は、then()メソッドのvalになります。

then()メソッドでチェーン

asyncの関数はreturnをつけなくてもPromiseのインスタンス(オブジェクト)を返します。
Promiseのインスタンスが返されるため、then()メソッドでチェーンすることができます。

async function init() {
  let val = await time(0);
  val = await time(val);
  val = await time(val);
  val = await time(val);
}
init().then(function () {
  console.log('end');
});

1秒ごとに0, 1, 2, 3と呼び出されたあと、最後のthen()メソッドが実行されてendが表示されます。

戻り値を設定

戻り値を設定すると、その値が返却されます。

async function init() {
  let val = await time(0);
  val = await time(val);
  val = await time(val);
  val = await time(val);
  return val;
}
init().then(function (val) {
  console.log(`end ${val}`);//end 4
});

throw new Error()でcatch()に移行

そしてthrow new Error()を記述すると、catch()メソッドが実行されます。

async function init() {
  let val = await time(0);
  val = await time(val);
  val = await time(val);
  val = await time(val);
  throw new Error();
  return val;
}
init()
  .then(function (val) {
    console.log(`end ${val}`); //end 4
  })
  .catch(function (err) {
    console.log(err); //Error
  });

このように、Promiseを動作は同じとなりますが、より直感的に記述できるのが、async/awaitとなります。

例外処理については、次の記事を参考にしてみてください。