LoginSignup
221

More than 3 years have passed since last update.

僕でもわかるasync/await

Last updated at Posted at 2019-09-01

サルでも分かるで挫折し、ミジンコでも分かるで挫折したわたしに。

サル > ミジンコ > 僕

僕でも分かるasync/awaitまとめました。
モダンブラウザで動きます。Developer Toolのコンソールで試してみてください。
(本記事のサンプルはgoogle.comドメインのページでお試しください。googleさんお邪魔します)

fetch APIで試す

ブラウザからAjaxリクエストなどに使えるfetch APIで試します。

jQueryなどのAjax通信を思い出すと、レスポンスを取得した際のロジックはコールバック関数で定義しますね。fetchを使うと以下のように同期処理っぽく書けます。

(async () => {
    const response = await fetch("https://www.google.com")
    const html = await response.text()
    console.log(new DOMParser().parseFromString(html, "text/html").title)
})()
実行結果
Google

awaitで呼び出すのはasyncで定義された関数です。
また、awaitはasyncで定義された関数の中で使う必要があります。
トップレベルなどで使うには上記のように無名関数で囲います。
(Chrome DevToolsのコンソールではasyncの無名関数が省略できます。便利。)

async function hoge() {
    await ...
}

(async () => {
    await hoge()
})()

ちなみにエラー処理はこんな感じ。

(async () => {
    try {
        const response = await fetch("https://not_exists_domain")
    } catch (error) {
        console.log(error)
    }
})()

ループ処理で使う

forEachで使う

forEachなどのコレクション用の関数内で利用するときは注意が必要です。
以下は構文エラーにはなりませんが、1週目と2週目が同時に実行されてしまいます。
しかもawait処理の終了を待ってくれません。


(async () => {
    ["https://www.google.com", "https://www.google.com/doodles/"].forEach(async (url) => {
        const response = await fetch(url)
        const html = await response.text()
        console.log(new DOMParser().parseFromString(html, "text/html").title)
    })
    console.log("finish")
})()
実行結果
finish
Google
Doodle

順次実行する

順番に実行するためにはforやfor-ofなどを使います。

(async () => {
    for (const url of ["https://www.google.com", "https://www.google.com/doodles/"]) {
        const response = await fetch(url)
        const html = await response.text()
        console.log(new DOMParser().parseFromString(html, "text/html").title)
    }
    console.log("finish")
})()
実行結果
Google
Doodle
finish

並列実行で全部終わるのを待つ

forEachをmapに変えてPromise.allを使います。

(async () => {
    const results = await Promise.all(
        ["https://www.google.com", "https://www.google.com/doodles/"].map(async (url) => {
            const response = await fetch(url)
            const html = await response.text()
            return new DOMParser().parseFromString(html, "text/html").title
        })
    )
    console.log(results)
    console.log("finish")
})()
実行結果
["Google", "Doodle"]
finish

まとめ

Promise.allが使えるのはasync/awaitの実体がPromiseだからですね。
async/awaitの入門記事にはPromiseから入るものが多く難しい印象でしたが、とりあえず使うためには本記事の理解くらいでもいいのかなーと思って書きました。

使い慣れてきたらPromiseの理解を深めていきましょう!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
221