サルでも分かるで挫折し、ミジンコでも分かるで挫折したわたしに。
サル > ミジンコ > 僕
僕でも分かる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の理解を深めていきましょう!