Edited at

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