今更ながら async/await を使ってみました。
- Standard ECMA-262 6th Edition / June 2015 ECMAScript® 2015 Language Specification
- ECMA-262 7ᵗʰ Edition / June 2016 ECMAScript® 2016 Language Specification
- ECMAScript® 2017 Language Specification (ECMA-262, 8th edition, June 2017)
- Draft ECMA-402 / February 16, 2018 ECMAScript® 2019 Internationalization API Specification
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 をつなげて記述する煩わしさがなくなっていいと思います。