lifehack blog

役に立つガジェットや知識を配信します

await についてまとめてみた

f:id:walk0204:20210904220146p:plain

記事目安...10分

はじめに

Promise, async ときたので、最後に await の備忘録も。

以前の関連記事は以下を参照ください。

Promise の基本プロセスについて図でまとめる - lifehack blog
async の基本プロセスついて図にまとめてみた。 - lifehack blog

await とは?

await で覚えておきたいことは大きく2つです。

①await は、定義することで、非同期関数内で同期的に処理を行います。
②await は、async で定義された非同期関数でしか使えません。

遷移図

await の役割は、Promise の状態に即して解説すると、appending が fulfilledもしくは、rejected になるまで待機することです。 従って await は Promise.prototype.then() と同じ役割をします。

f:id:walk0204:20210904220350p:plain

黒色の四角は、実行される関数を、
水色の四角は、Promise のステータスを表します。async のステータスではないので注意。

以前、触れた async の基本プロセスと比較すると分かりやすいと思います。

参考: https://walk0204.hatenablog.com/entry/tech/programing/nodejs/async-process

await をコードで解説

「非同期関数内で同期的に処理」というのは、少しとっつきにくいので、コードで解説します。

async は 一時的に、Promise を返すことで、関数を非同期にしています。
しかし、ケースによっては、非同期関数の処理を待ってから他の処理を実行したい場合があります。
次に実行される関数が、非同期関数の処理結果を参照する場合などです。

例えば、スクリプトを使って、 "fuga" の文字列を出力したいケースを考えてみます。

■ sample-not-await.js

hoge = async () => {
    return "fuga";
}

main = () => {
    value = hoge()
    console.log(value)
}

main()

一見、value 変数が "fuga" の文字列を受け取りそうに見えます。 しかし実行すると、一時的に async で渡された Promise が入り、console.log(value) が非同期実行されてしまいます。

$ node sample-not-await.js
Promise { 'fuga' }

従って await を使います。

■ sample-await.js

hoge = async () => {
    return "fuga";
}

main = async () => { //await は async で定義された非同期関数内でしか使えない。
    value = await hoge() //await を追加して、"fuga" が return されるまで待つ。
    console.log(value)
}

main()

await を入れることで、hoge() が "fuga" を return するまで待機してから、value 変数に出力結果を格納するという同期的な処理が実現できます。

$ node sample-await.js
fuga

コードをシーケンス図でも解説

さきほどのコードの処理をまとめると以下フローになります。

■ sample-not-async.js の場合

f:id:walk0204:20210904220431p:plain

■ sample-async.js の場合

f:id:walk0204:20210904220515p:plain

まとめ

await 使うと 非同期関数の処理を柔軟かつ、可読性高く実装できるので、ぜひ使ってみてください~