はじめに
Nodejs の async/await について、自分なりに整理してまとめてみました。
本記事と対照に書いた Promise.prototype.then() に関する こちら の記事も見ていただけると理解しやすいと思います。
具体例を交えて解説するので参考にしてみてください!
記事目安...10分
async/await とは
用語整理
async
宣言することで、関数を非同期関数にします。
async で宣言された関数は、Promise オブジェクト同様、仮の値を返すようになります。
使用することのメリットは、 Promise オブジェクトを使うよりもコードの可読性を向上できる点です。
await
宣言することで、非同期関数の処理結果(return メソッドで返される値)を取得出来ます。
await は async が宣言された関数内でしか使用できません。
Promise と async/await の対応表
それぞれの用法を対応表でまとめてみました。
Role | Promise | async/await |
---|---|---|
関数を非同期にする | Promise() | async |
非同期関数の成功時の結果を返す | resolve | return |
非同期関数のエラー時の結果を返す | reject | throw |
非同期関数の処理結果を取得する | Promise.prototype.then() | await |
では、サンプルコードを交えて解説していきます。
具体例を用いた async/await の解説
今回は、「1st, 2nd, 3rd」を順番にコンソールに表示するようコードを作成します。
〇 期待する結果
1st 2nd 3rd
パターン1: async/await を使用しない場合
サンプルコード
function myAsync() { return "2nd" } function main() { console.log("1st"); const second = myAsync() console.log(second) console.log("3rd") } main()
出力結果
1st 2nd 3rd
解説
当然ですが、期待通りの結果となりました。
上から下に素直にコードが流れていくので、myAsync() の処理結果である 「2nd」 が second
変数に期待通りに格納されています。
またポイントとして、main() および、 myAsync() が 同期処理関数 です。
パターン2: async のみを使用した場合
サンプルコード
async function myAsync() { return "2nd" } function main() { console.log("1st"); const second = myAsync() console.log(second) console.log("3rd") } main()
出力結果
1st Promise { '2nd' } 3rd
解説
コンソールへの出力が期待通りとなりませんでした。
「2nd」が出てほしいところに「Promise { '2nd' }」が返っています。
これは 非同期処理関数 myAsync() が最初に返した仮の値 「Promise { '2nd' }」が、 second
変数に格納されてしまったため です。
このことからも分かるように async がついたことで、 myAsync() が 非同期処理関数 に変化しています。
main() はパターン1同様、同期処理関数です。
パターン3: async/await を使用した場合
サンプルコード
async function myAsync() { return "2nd" } async function main() { console.log("1st"); const second = await myAsync() console.log(second) console.log("3rd") } main()
出力結果
1st 2nd 3rd
解説
async/await を両方使用すると、コンソールへの出力が期待通りとなりました。
const second = await myAsync()
これは上記の部分で、 await が、即座に myAsync() から返ってくる 仮の値 「Promise { '2nd' }」ではなく、
myAsync() の実行結果である 「2nd」 を second
変数に格納してくれたため です。
またポイントとして、main() および myAsync() が 非同期処理関数 です。(*1)
*1. main() の非同期処理関数化について
最初に申し上げた通り await は async を宣言した関数内でしか使用できないため、
async function main() {
上記のように main() を無理やり async を使って非同期処理関数にしています。
そうゆう仕様なのでしょうがないですが、async を宣言しなくても await を使えるようにすればいいのにと思いました。
この仕様について理由がわかる人いたらコメントいただけると幸いです。
まとめ
ということで若干解決していない部分もありますが、 async/await を使った非同期処理についておおむね理解していただけたのではないでしょうか。
Promise よりも簡潔かつ、わかりやすくコードを書けることも一目瞭然ですね。
特に return で値を返せるのがわかりやすくていいなと思いました。
以上ご覧いただきありがとうございました。
菅谷 歩 (記事一覧)