Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
225
Help us understand the problem. What is going on with this article?
@yatemmma

僕でもわかるasync/await

More than 1 year has passed since last update.

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

サル > ミジンコ > 僕

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

225
Help us understand the problem. What is going on with this article?
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
yatemmma
鳥取にいます
lassic
ITを駆使して地方を元気にする株式会社LASSIC(ラシック)。地方を舞台に自分らしく働く優秀な技術者が、貴社のWEB・スマートフォンサイトやアプリ開発、システム開発プロジェクトを成功へと導きます。~鳥取発~ITで地方創生

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
225
Help us understand the problem. What is going on with this article?