一定間隔で実行する処理は 場合によっては setIntervalではなくsetTimeoutで書こう!
例: 約5秒毎にHTTPリクエストを投げてください
こんな処理を実装するときの例です。
各メソッドのおさらい:
主な役割 | |
---|---|
setInterval | nミリ秒間隔でなにか処理をさせる |
setTimeout | nミリ秒後になにか処理をさせる |
※遅延等は考慮しません
setInterval
普通に考えると、setInterval
で簡単に実装できそうです。
const fetchDataInInterval = () => {
fetchData()
setInterval(() => {
fetchData()
}, 5000)
}
↓このような動きになるかと思います。
(黒がsetInterval
緑がfetchData
)
(fetchData
に約1秒かかる想定)
問題点
例えば、サーバー不調や、クライアント側のネットワーク不調でfetchData
に20秒以上かかってしまう場合どうなるでしょうか?
↓のように、前のレスポンス状況に関わらず、5秒毎に容赦なく次のリクエストを実行してしまいます。
setTimeout
setTimeoutを使い、前のリクエストが終わってから5秒後に実行するような処理に変えてみました。
const fetchDataInInterval = () => {
fetchData().then(() => {
setTimeout(() => {
fetchDataInInterval()
}, 5000)
})
}
↓図にすると、このような動きに変わりました。
↓通信に時間がかかった場合こうなるため、渋滞問題は起きません。
その他の違い:
- 5秒毎ではなく、5秒+通信時間の間隔で実行される
- then/catch/finallyの扱い次第で、例外時の動作が変えられる
- 例えば上記のコードでは、thenのときだけ次回の通信を実行しているので、失敗したら以降の通信が中断されます
次の処理の実行を自分で書くので、こちらのほうが色々と実装の自由度が高そうです。
おわりに
- setTimeoutを使うとsetIntervalとは違った挙動の定期処理を書ける
- 例のようにsetTimeoutのほうが向いているケースがある
という話でした。
setIntervalでよいケースや、setIntervalのほうが適切なケースも当然ありますので、あくまで一例としてご参考にしていただければと思います。