LoginSignup
3
3

More than 3 years have passed since last update.

setTimeoutを使って指定時間後に処理を行う際はスリープに注意

Last updated at Posted at 2020-01-16

setTimeoutで数秒ではなく数十分など長めに設定した場合に、上手く挙動しなかったことがありました。

setTimeout

指定時間後にJavaScript関数を実行するsetTimeout。
ページを開いたまま20分経過したら自動で指定ページに遷移させようとしました。

setTimeout(function(){
   window.location.href = 'https://xxx.ne.jp/';
}, 20 * 60 * 1000);

普通思い浮かぶであろうこのコードでなんの問題もなく処理が動きそうです。(と思ってました...)

ただ、このsetTimeoutはAndroidやiOSといったスマホ・タブレット端末のWebブラウザでは注意する必要があります。
スマホ・タブレット端末では、アプリがバックグランドに入るスリープの概念があり、この状態ではsetTimeoutの呼び出し(JavaScriptの実行そのもの)も保留されてしまいます。
スリープ中に止まったタイマーが完了するのは、1分後かもしれないし10分後、1時間後かもしれません...。

経過時間をチェックしてスリープ対策

スマホユーザーが多いサービスがゆえにスリープ対策をどうしてもしなければならなかったので、setIntervalで「ページを開いてから20分経過したか」を定期的にチェックし続ける処理を入れることにしました。

  • setTimeout関数 ・・・ 指定した時間経過後に処理を実行する
  • setInterval関数 ・・・ 指定した時間ごとに処理を実行する
  • clearTimeout関数 ・・・ setTimeoutで設定したタイマーを取り消す
  • clearInterval関数 ・・・ setIntervalで設定したタイマーを取り消す

※時間の指定単位は「ミリ秒」

// 20分後指定URLにリダイレクト
const setTime = Date.now() + (20 * 60 * 1000);

const timer_Id = setInterval(() => {
if (Date.now() > setTime) {
  clearInterval(timer_Id);
  window.location.href = 'https://xxx.ne.jp/';
}
}, 500);

この処理だと、途中でスリープしていた場合でも

  • ページを開いてから20分後に処理が走る
  • スリープ中に20分を過ぎていたら復帰した瞬間に実行される

今回は1秒だと微妙だったので0.5秒(500ミリ秒)でIntervalを指定しました。

最後に

「Webブラウザがバックグラウンドに回ってスリープ状態になり処理が止まる」という事象はPCでは起こりにくいので、AndroidやiOSで挙動が変わることがあるという点は注意すべきところですね。

3
3
1

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
3
3