【Javascript】タイマー処理においてのSetTimeout
GPSロガーをWebアプリで開発
Webアプリで、一定間隔毎になにか処理をさせたいときにはJavascriptを使う。
ところが、これが少し曲者だったりする。
例えば、GPSロガーをWebアプリで実装しようとする。一定時間毎にDBにGPS情報を登録する。
Javascript側でDBに書き込みせずにAjaxで書き込みしようとする。
こちらが実際に書き込みを行う部分
var interval=5000; var sendgeo = function(){ if (navigator.geolocation) { // 現在の位置情報取得を実施 navigator.geolocation.getCurrentPosition( // 位置情報取得成功時 function (pos) { //取得したGPS情報を画面に書き出す var location ="<li>"+"緯度:" + pos.coords.latitude + "</li>"; location += "<li>"+"経度:" + pos.coords.longitude + "</li>"; var nDate = new Date(); location += "<li>"+"時刻:" + nDate.getHours() + ":" + nDate.getMinutes() + ":" + nDate.getSeconds() + "</li>"; //ajaxにて現在地をDBに書き込む var data = { bus : $('#bus').val(), lat : pos.coords.latitude, lng : pos.coords.longitude, }; //Ajax通信メソッド //type : HTTP通信の種類(POSTとかGETとか) //url : リクエスト送信先のURL //data : サーバに送信する値 $.ajax({ type: "POST", url: "sendgeo.php", data: data, dataType: "html", //Ajax通信が成功した場合に呼び出されるメソッド success: function(html){ $('#location').html(location); $('#result').html(html); } }); }, // 位置情報取得失敗時 function (error) { var message = ""; switch (error.code) { // 位置情報取得できない場合 case error.POSITION_UNAVAILABLE: message = "位置情報の取得ができませんでした。"; break; // Geolocation使用許可されない場合 case error.PERMISSION_DENIED: message = "位置情報取得の使用許可がされませんでした。"; break; // タイムアウトした場合 case error.PERMISSION_DENIED_TIMEOUT: message = "位置情報取得中にタイムアウトしました。"; break; } window.alert(message); }); } else { window.alert("本ブラウザではGeolocationが使えません"); } }
この処理を一定間隔で起動するために
$(document).ready(function() { var id; var setCurrent = function(){ sendgeo(); id = setTimeout(setCurrent, interval); } });
setTimeoutで、自分自身を読み出すことで無限ループを実現している。
問題発生
ところが、このスクリプトはPC上ではうまく動くがスマホではうまく動かない。
ログが書き込まれた時刻を見ると、「同じ時刻に数件書き込まれる」
が繰り返され、等間隔に記録されているとは言い難い。
原因
setTimeoutの仕様を調べてみると、「指定された時間が経過したら実行」ではなく
「指定された時間が経過したら実行キューに登録」であった。
そして、実行キューにはいったタスクを実行するタイミングが
おそらくスマホではリアルタイムではなかったということだろう。
実行すると約束したが、いつ何時とまでは約束していないっ......
ってことかな。