Help us understand the problem. What is going on with this article?

僕でもわかるasync/await

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

サル > ミジンコ > 僕

僕でも分かる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の理解を深めていきましょう!

yatemmma
鳥取にいます
lassic
ITを駆使して地方を元気にする株式会社LASSIC(ラシック)。地方を舞台に自分らしく働く優秀な技術者が、貴社のWEB・スマートフォンサイトやアプリ開発、システム開発プロジェクトを成功へと導きます。~鳥取発~ITで地方創生
https://www.lassic.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした