7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

一定間隔で実行する処理はsetIntervalではなくsetTimeoutで書こう

Last updated at Posted at 2021-12-06

一定間隔で実行する処理は 場合によっては setIntervalではなくsetTimeoutで書こう!

例: 約5秒毎にHTTPリクエストを投げてください

こんな処理を実装するときの例です。

各メソッドのおさらい:

主な役割
setInterval nミリ秒間隔でなにか処理をさせる
setTimeout nミリ秒後になにか処理をさせる

※遅延等は考慮しません

setInterval

普通に考えると、setIntervalで簡単に実装できそうです。

const fetchDataInInterval = () => {
  fetchData()
  setInterval(() => {
    fetchData()
  }, 5000)
}

↓このような動きになるかと思います。

setTimeout_1.png

(黒がsetInterval 緑がfetchData

fetchDataに約1秒かかる想定)

問題点

例えば、サーバー不調や、クライアント側のネットワーク不調でfetchDataに20秒以上かかってしまう場合どうなるでしょうか?

↓のように、前のレスポンス状況に関わらず、5秒毎に容赦なく次のリクエストを実行してしまいます。

setTimeout_2.png

setTimeout

setTimeoutを使い、前のリクエストが終わってから5秒後に実行するような処理に変えてみました。

const fetchDataInInterval = () => {
  fetchData().then(() => {
    setTimeout(() => {
      fetchDataInInterval()
    }, 5000)
  })
}

↓図にすると、このような動きに変わりました。

setTimeout_3.png

↓通信に時間がかかった場合こうなるため、渋滞問題は起きません。

setTimeout_4.png

その他の違い:

  • 5秒毎ではなく、5秒+通信時間の間隔で実行される
  • then/catch/finallyの扱い次第で、例外時の動作が変えられる
    • 例えば上記のコードでは、thenのときだけ次回の通信を実行しているので、失敗したら以降の通信が中断されます

次の処理の実行を自分で書くので、こちらのほうが色々と実装の自由度が高そうです。

おわりに

  • setTimeoutを使うとsetIntervalとは違った挙動の定期処理を書ける
  • 例のようにsetTimeoutのほうが向いているケースがある

という話でした。

setIntervalでよいケースや、setIntervalのほうが適切なケースも当然ありますので、あくまで一例としてご参考にしていただければと思います。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?