ガクセイハッカソン

現役エンジニアが教える!実践JavaScript入門 〜非同期処理発展編〜

2022-07-31 公開

今回扱う内容:非同期処理

非同期処理の応用的な使い方を理解しよう。

コールバック関数を使った非同期処理

タイマー処理

setTimeoutは第2引数にミリ秒で指定した時間後に第1引数のコールバック関数がよばれます。

次のように記述することで1秒後にHelloが出力されます。

setTimeout(() => {
    console.log("Hello");
},1000);

コールバック地獄

前述のPromiseを使わない非同期処理では、「コールバック地獄」と呼ばれる問題があります。

setTimeout(() =>{
   console.log("Hello!");
   setTimeout(() =>{
      console.log("Hello!");
      setTimeout(() =>{
         console.log("Hello!");
         setTimeout(() =>{
            console.log("Hello!");
         }, 1000);
      }, 1000);
   }, 1000);
}, 1000);

次のようにPromiseを使えば、非同期処理を何回呼んでもネストが深くなりません。

asyncHello()
   .then(() => asyncHello())
   .then(() => asyncHello())
   .then(() => asyncHello())
   .catch((error) =>{
      console.log("error");
   });

非同期処理の直列実行と並列実行

直列で非同期処理を行う場合は、for...of文を使うことで、非同期処理の反復処理を実現します。

const ids = [1, 2, 3, 4, 5];
const main = async () => {
  for (const id of ids) {
    const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
    const json = await res.json();
    console.log(json);
  }
};

main();

並列で非同期処理を行う場合は、Promiseの配列をPromise.allに渡すことで実現できます。

const ids = [1, 2, 3, 4, 5];
const main = async () => {
  const fetches = ids.map((id) =>
    fetch(`https://jsonplaceholder.typicode.com/todos/${id}`).then(res =>
    res.json()
    )
  );
  const jsons = await Promise.all(fetches);
    console.log(jsons);
};

main();

まとめ

Promiseとasync/awaitを用いた非同期処理の記述方法を解説しました。次回はJavaScriptのDOM操作について解説します。

関連記事