One thing that I’ve seen lots of people ask questions about is how to reliably pause or sleep execution of Javascript code. There are a variety of solutions, however none seem to be reliable as Javascript cannot really handle this functionality, except if you use setTimeout, which is no good if you just want to not consider any events, and you just want a bog standard sleep like PHP has. With jQuery, the need is reduced a little bit because you can use event callbacks to delay execution of the script until certain events have completed.
But what if you need to implement this and you need it to be reliable? What if you just have to delay execution for x number of seconds? Here’s a very simple way I came up with.
Use PHP
Think about it – PHP has the sleep(); function which works like a charm for delaying execution. So why not just combine the two? If we create a PHP page to handle an incoming Javascript request, sleep(); execution for a given number of seconds, then return output to Javascript, this pauses execution.
PHP code
OK so let’s first make a PHP page. Call it sleep.php and use the following code.
<?php
// Do we have a duration time?
if (isset($_GET['duration']) && is_numeric($_GET['duration'])) {
$duration = $_GET['duration'];
} else {
// If not, just say 1 second.
$duration = 1;
}
sleep($duration);
echo "ok";
?>
All we do here is expect a GET variable of duration. If it’s there, and it’s numeric, we’ll sleep to it’s value. Then when sleep is finished, we’ll echo back “ok” to the browser. You can test this functionality by just performing a direct request to it and passing ?duration=5 for a five second pause, for example.
The Javascript
Now we can just create an ordinary HTML page with our Javascript in. We can create a function called js_sleep() for example that handles our callback for us.
// Our pause function.
function js_sleep(duration) {
if (duration == undefined || isNaN(duration)) {
duration = 1;
}
$.ajax({
url: 'http://path-to/sleep.php',
type: 'GET',
data: {duration: duration},
success: function(response) {
if (response == "ok") {
alert('Timer finished');
}
}
})
}
With that code there we can quite easily call it in our Javascript code as js_sleep(3) to create a pause of three seconds anywhere. Obviously you’d probably want to modify that code to return true; or nothing at all, rather than alert.
Problems with this method
Although this works great and isn’t too hard to implement, the biggest problem is that the request will usually be a little bit longer, as the user’s browser has to perform the callback to the server and wait for the response. Testing on Firebug, I discovered that it usually adds about 100-300ms to the request.
