指定時間後に指定のJavaScript関数を実行するsetTimeout()。Webゲーム開発のメインループに使用される機会も多いですね。 ただ、このsetTimeout()はAndroidやiOSといったスマートフォン/タブレット端末のWebブラウザでは注意する必要があります。スマートフォンやタブレット端末では、アプリがバックグランドに入るスリープの概念があり、この状態ではsetTimeout()の呼び出し(というかJavaScriptの実行そのもの)も保留されてしまうのです。 たとえば、JavaScript関数func_a()の最後に
と記述することで「30ms程度の間隔でfunc_aが呼び出される」メインループを作ったとしましょう。この関数は、Webブラウザが前面に表示されユーザーが操作を行っている間は確かに30ms程度ごとに呼び出されます(もちろんfunc_aの処理内容次第ですが)。 しかし、省電力機能でスリープしたりユーザーがホームボタンを押すなどしてWebブラウザがバックグランドに隠れてしまえば、次に呼び出されるのは復帰後ということになるのです。その場合、func_aが呼び出されるのは、1分後かもしれないし10分後、1時間後かもしれません。 この問題は、「前回の処理からの経過時間」によって処理を行う場合に問題になる点です。たとえば、前回の経過時間に応じてマップのスクロール量を決めるような場合ですね。30ms程度ごとに呼び出されることを前提に、単純に「経過ms/30」ピクセルスクロールさせるようなことをしたら、前回からの呼び出しに1分かかったような時にはとんでもない位置にスクロールすることになります。 スリープなどによるsetTimeout()の呼び出し問題を解決するには、以下の点が重要です。
こうした「Webブラウザがバックグラウンドに回ることで処理が止まる」問題は、PCでは起こりにくいので、特にPCで動かしていたWebシステムをAndroidやiOS向けに移植する際は、注意したい点ですね。 |