ECMAScript® 2017 の async/await を使ってみました

今更ながら async/await を使ってみました。

async/await は ECMAScript® 2017 で正式に採用されたみたいです。 現在は 2018 年なので、もう 1 年も前のことなのですね。 現在は ECMAScript® 2019 が Draft なのでしょうか。

環境

  • Node.js: v8.9.4

async/await を使わない場合

async/await を使わない場合は、 then をつなげていました。

// async.js
const resolveAfter3Seconds = (x) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`resolved ${x}`)
    }, 3000)
  })
}
const main = () => {
  resolveAfter3Seconds(1).then((value) => {
    console.log(value)
    return resolveAfter3Seconds(2)
  }).then((value) => {
    console.log(value)
    return resolveAfter3Seconds(3)
  }).then((value) => {
    console.log(value)
  })
}
main()

Node.js で実行してみます。

$ node async.js
resolved 1
resolved 2
resolved 3

3 秒ごとに resolved n が表示されました。

async/await を使う場合

Promise を返す関数(resolveAfter3Seconds)を呼び出すところは await をつけました。 それを定義している関数自体(main)には async をつけました。

// async.js
const resolveAfter3Seconds = (x) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`resolved ${x}`)
    }, 3000)
  })
}
const main = async () => { // async をつける
  console.log(await resolveAfter3Seconds(1)) // await をつける
  console.log(await resolveAfter3Seconds(2)) // await をつける
  console.log(await resolveAfter3Seconds(3)) // await をつける
}
main()

実行してみます。

$ node async.js
resolved 1
resolved 2
resolved 3

こちらも 3 秒ごとに resolved n が表示されました。

エラーの場合

エラーの場合は try…catch なのかな。 Promise を返す関数の中で、 3 回目は拒否するようにしました。 呼び出す側は try…catch で例外を捉えるようにしました。

// async.js
const resolveAfter3Seconds = (x) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (x === 3) {
        reject(`reject ${x}`) // 3 回目は拒否する
        return
      }
      resolve(`resolved ${x}`)
    }, 3000)
  })
}
const main = async () => {
  try { // try...catch で囲む
    console.log(await resolveAfter3Seconds(1))
    console.log(await resolveAfter3Seconds(2))
    console.log(await resolveAfter3Seconds(3))
  } catch (e) { // 例外を捉える
    console.log(`catch: ${e}`);
  }
}
main()

実行してみます。

$ node async.js
resolved 1
resolved 2
catch: reject 3

3 回目は拒否されたので、 catch に入って e がコンソールに出力されました。

終わり

then をつなげて記述する煩わしさがなくなっていいと思います。

参考