JavaScript

【JS】連続するsetTimeoutをスッキリさせる【コピペで解消】

投稿日:

こんにちは。
今回はJavaScript(以下JS)で連続でsetTimeout()を実装する時によく陥る「コールバックヘル」を解消する方法を記載します。

なお、コピペで完結させたいので難しい用語の解説は一切抜きにしています。
解説は別の記事で書こうと考えております。

とりあえず、速攻でsetTimeout()をスッキリさせたい、見やすくさせたい!って方はこの記事のコードをコピーすればOKかと思います。

連続でsetTimeout()を使うとどうなる?

実際に記述してみます。

setTimeout(() => {
  console.log('1秒経ちました');
  setTimeout(() => {
    console.log('2秒経ちました');
    setTimeout(() => {
      console.log('3秒経ちました');
      setTimeout(() => {
        console.log('4秒経ちました');
      }, 1000);
    }, 1000);
  }, 1000);
}, 1000);

この記述は1秒ごとに○秒経ちましたとカウントするようにしている記述です。
つまり、
1秒経てば、「1秒経ちました」
2秒経てば、「2秒経ちました」
3秒経てば、「3秒経ちました」….
とコンソールに出てきます。

いかがでしょう?見にくいと感じましたでしょうか?
今回の例だと「console.log(‘○秒経ちました’);」の一文なので割と見やすいですが、この「console.log(‘○秒経ちました’);」の部分に数行にわたる関数が記載されているとどうでしょう?
かなり見にくくなり、「あれ?何秒後に何の記述してるんだっけ?」と言う状況に陥ります。

ちなみに、上記の例のようにsetTimeoutを繰り返し使うことによってコールバックのネストが深くなっていくことを「コールバックヘル」と言います。
コールバックヘルの特徴として、下の画像のように左側に三角形が入るような見え感になります。

さぁコピペはここからだ!

下記のコードをコピペすれば見にくいsetTimeoutのコールバックヘルを解消することができます。
コピー用のソースコードはもう少し下の方に用意しております。

const wait = function (seconds) {
  return new Promise(function (resolve) {
    setTimeout(resolve, seconds * 1000);
  });
};


wait(1)
  .then(() => {
    console.log('1秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('2秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('3秒経ちました');
    return wait(1);
  })
  .then(() => console.log('4秒経ちました'));

これで先ほどと同じ動作をします。

new Promise, resolve, then,,,,,???となると思いますが、
この記事の目的は「コピペで実装」なのでこれらの説明は割愛します。

コピペする部分は2つに別れます。
まず上部の

const wait = function (seconds) {
  return new Promise(function (resolve) {
    setTimeout(resolve, seconds * 1000);
  });
};

これが秒(時間)をコントロールしている部分となります。
そして下部、

wait(1)
  .then(() => {
    console.log('1秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('2秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('3秒経ちました');
    return wait(1);
  })
  .then(() => console.log('4秒経ちました'));

ここに待って欲しい「秒」と「動き」の記述をします。

wait()の中に書いている数字が「待って欲しい秒」です。
そしてthenのなかに「動作」を記述します。
thenのなかにreturn wait()で次の挙動まで待って欲しい秒を入れます。

コピペ用ソースコード↓

const wait = function (seconds) {
  return new Promise(function (resolve) {
    setTimeout(resolve, seconds * 1000);
  });
};


wait(○) // 待って欲しい○秒書く
  .then(() => {
   // ▼▼挙動を書く▼▼
     
   // ▲▲挙動を書く▲▲ 
    return wait(○); //待って欲しい○秒書く
  })
  .then(() => {
    // ▼▼挙動を書く▼▼
     
    // ▲▲挙動を書く▲▲ 
    return wait(○); //待って欲しい○秒書く
  })
  .then(() => {
    // ▼▼挙動を書く▼▼
     
    // ▲▲挙動を書く▲▲
    return wait(○); //待って欲しい○秒書く
  })
  .then(() => {
    // ▼▼挙動を書く▼▼
     
    // ▲▲挙動を書く▲▲
  });

今回の例だと4つの挙動ですが、発生させたい挙動数に応じてブロック数を調整してください。

まとめ

いかがでしょうか?
上記のソースだとそれぞれの挙動を書く時にブロックが並列になっているのでコールバックヘルに陥らずに、きれいに書けます。
また「○秒後に,,,」って言うのも挙動を書くブロックのすぐ下にあるので視覚的にわかりやすいですね。


今回は以上となります。
皆さんの理解の手助けとなっていれば幸いです。


▼▼人気の記事▼▼

【経験談】給料を上げたいなら自分に対しての出費を増やそう【自己投資のススメ】

-JavaScript
-, , , , , ,

執筆者:

関連記事

JS

【JavaScript】if文の基本から応用までを網羅。初心者・ド忘れした方にオススメ

こんにちは。今回はJavaScript(以下JS)の基本公文の一つであるif文について書いていきます。時間、計算、大小関係などの様々な条件で処理を変えたり、コンテンツの表示を変えたりと何かとよく使うi …

JS

【JS】forEach・map・filter・reduce それぞれ説明【配列実践スキル】

こんにちは。今回はJavaScript(以下JS)の基本である配列について書きたいと思います。配列の中でも特に下記にフォーカスを当てていきます。SEOガン無視の短い内容となってますので、サクッと見れま …

JS

newとインスタンスの関係

newとインスタンスについて自分なりに理解した流れを書きます。

JS

【JS】イベントリスナー’ DOMContentLoaded ‘と’ load ‘の違いを解説

こんにちは。今回はJavaScript(以下JS)のロード系?のイベントリスナーについて書きたいと思います。 ・DOMContentLoaded・load これらのイベントリスナーはJSを学習しはじめ …

JS

【JS】8分で理解 deferとasyncを図で説明してみた【図解】

こんにちは。今回はJavaScript(以下JS)の「defer属性」と「async属性」について解説します。これらの属性を使うことでページの表示速度をあげることが出来るのでぜひ理解しましょう。早速、 …

me

Taka

学生時代にアメリカ(サンフランシスコ)とカナダ(トロント)にそれぞれ約1年間づつ住んでいました。特にサンフランシスコではシリコンバレーに訪れた際にITの素晴らしさに触れ感動しました。IT業界で働くと決心した瞬間でもありました。現在はWeb制作に携わる会社員です。