user192632 user192632 - 3 months ago 6
jQuery Question

How to get a recursively called setTimeout function stay alive when in background

I have a web page that recursively calls a function using setTimeout. The page also has an html5 sms link (js redirection not href). When msg app launches, the web page does not appear to continue to run the functions in the background that I had hoped they would. I use a global counter variable to count and show on page how many times the checkAuth background function has run, and when I return to the page, the number did not increment every 3 secs like it was when I was first on the page, nor did it start incrementing again every 3 secs like I had hoped. Both functions appear to work on first go until msg app sends browser to background.

Even if they don't run in background I'm ok with that, but how do I get it to start back up again when in foreground? That's the minimum that I need to happen. Thx.

//event that starts the process
$("#connect").click(function (){checkAuth();});

function checkAuth() {

//global var that counts how many times this function is called
authAttempts++;

//displays checkAuth run count on page.
$("#aa").text(authAttempts.toString());

$.get(encodeURI("myurl.aspx?phone=" + getCookie("phone") + "&ec=" + getCookie("ec") + "&authToken=" + getCookie("at") + "&uh=" + getCookie("uh") + "&mode=" + getCookie("mode")), function (data) {
$("#ajaxResults").html(data);
if ($("#authYes").length) {
var mode = getCookie("mode");
if (mode == "drv") {
window.location.replace("drv.aspx" + query);
}
else if (mode == "dsp") {
window.location.replace("dsp.aspx" + query);
}
}

else if ($("#authPending").length) {

if (++attempts >= 10) {
alert("Authentication Timed-out. Please try to connect again");
$("#link").html("");

// if this times out then force a new authentication value
// to keep the pending value from being stuck

var r = Math.random() * 1000000000;
var ri = r.toFixed(0);
var aToken = ri.toString();

$("#at").val(aToken);
setCookie("authToken", aToken, 1);
}
else {
setTimeout(checkAuth, 3000);
}
}

//must have been no good so start the authentication process
//authSent is global var to record if auth has already been sent
else if (authSent == false) {
authSent = true;
sendAuth();
}
});
}

function sendAuth() {
// generate a new token

var r = Math.random() * 1000000000;
var ri = r.toFixed(0);
var aToken = ri.toString();

$("#at").val(aToken);

setCookie("at", $("#at").val(), 1);

checkAuth();
//launch msgs app so they can send a prefilled text message
setTimeout(showMsgsApp, 500);
}
function showMsgsApp() {
window.location = "sms:19789652017&body=" + $("#at").val() + "-" + $("#ec").val() + "-" + $("#mode").val() + "-" + $("#uh").val();
}

Answer

You could use a web worker, to get your code executed even when your page is on the background, I haven't tested it on phone with your case, but it does work, for executing code, while a chrome tab is open, and not active, so it might suite your need.

The idea is to use a webworker that will run the timeout recursively, and on every tick, post a message to the window, the window will listen for given messages, and execute the checkAuth, each time it receives a message.

example:

create a simple webworker: worker.js

setInterval(function(){
  postMessage('triggerAuth');
}, 3000)

now on your page, instead of creating the first timeout, you should execute the webworker:

var authWorker = new Worker("worker.js");

authWorker.onmessage = function (oEvent) {
   checkAuth();
};

then make sure after you have completed the operation successfully, to terminate the worker.

authWorker.terminate();

the reason is, that while the tab isn't active, it won't respond to the timeouts or intervals, thats why your code isn't being executed.

again, this is tested with un active browser tabs, not sure if it will be the same with your mobile example.

Comments