JavaScript Sleep: Scheduling Tasks Asynchronously

sleep JavaScript If you are new to web programming, it is a whole new world of ideas and concepts in addition to algorithmic ideas, which you may already be familiar. But you have easy ways to catch up, so don’t worry yet!

One key idea in web programming is the separation between the client-side and the server-side code; languages and frameworks like Django, Ruby-on-Rails allow you to serve up content from the server-side. Whereas JavaScript, the new Dart-lang, and in the past VB Script from Microsoft, are techniques used to shape user experience by programming the HTML pages on the client-side browsers.

This blog post focuses on the challenges of client-side programming when you have to delegate events at specified times, without using sleep() like methods usually available in the traditional programming languages. Read on about client-side programming and challenges of writing code asynchronously.

Preliminaries

Introduction to Event-Driven Programming

Client-side programming involves writing JavaScript code that runs in tandem with the browser. This means essentially,

  1. main-thread of execution of the program belongs to the browser

  2. when you run code like sleep it stops the browser from interacting with the user

  3. user interaction events that involve data procession should be run in separate thread, or asynchronously

  4. concepts like AJAX, ‘asynchronous JavaScript and XML’, become relevant for long running tasks returned to the host server-side

  5. callbacks are used to handle user events.

So what does this mean for you to write code like ‘sleep’ in the user thread? The browser seems to freeze. The alternatives are called ‘setTimeout’ function and ‘setInterval’ in JavaScript. Read on to figure out how.

Developing In JavaScript

You don’t need to download any JavaScript package to try these examples. They work on any browser, and you may want to get Google Chrome or Mozilla Firefox for convenience of testing.

Asynchronous Programming in JavaScript

Browser and JavaScript engine have to run simultaneously. So there is no single concept of a sleep function, but general idea of asynchronous delayed execution.

Imagine a office secretary at work. She has to take phone calls, arrange sandwiches for lunch meeting, and pickup the mail and notes for the boss during the morning. She essentially needs to delegate work for others and herself at later time by scheduling tasks.

In pseudo-code we can write the situation when she comes to work as,

  //arrive at work @ 8.00AM
  schedule a sandwich pickup at 11.00AM, i.e. 3hrs from now
  schedule mail pickup at 3:30PM, i.e. 7.30hrs
  while( time < 5.00PM )
        continue the phone calls, meetings, etc.
        if (  time for scheduled events )
              do_scheduled events

What we have done with this program is to instruct the computer to act as a secretary by scheduling the events, usually setInterval or setTimeout commands. In JavaScript these functions are roughly achieved by, calls like,

	      setTimeout('pickup_sandwich',3*60*1e3);//timeout after 3hrs

Functions – setTimeout and setInterval

The two functions which carry out the delayed executing are setTimeout, and setInterval. The only difference being that setTimeout runs the given JavaScript code one time, after the said number of milliseconds. It is use typically like,

	setTimeout('function_or_script_to_execute_delayed()',time_in_ms)

The setInterval() method is similar but the execution repeatedly calls the function or script at the end of delay until the interval function is disabled via the clearInterval() call, usually within the function that is repeatedly called.

var interval_id = setInterval('function_or_script_to_execute_delayed()',time_in_ms);

//somewhere within the function_or_script code,
clearInterval( interval_id );

Example – Delayed Execution

If you want to greet a user on your website after the first 30s they have loaded the page, you can try using the delayed execution,

<html>
<head>
<script src="./jquery.js"></script>
<script type="text/javascript">
var init = function() {
   console.log("Init fcn");
   setTimeout('greet_user();',30*1e3); //after 30s
};

function greet_user() {
  window.alert('Hello user! Your browser is '+navigator.userAgent)
  console.log('Hello user! Your browser is '+navigator.userAgent)
}

</script>
</head>
<body onload="init();">
<input type="entry" id="widget"> </input>
</body>
</html>

and saving it as ‘timeout_demo.html’ you should see, the alert dialog box with a message like,

Hello user! Your browser is Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36

in your Chrome browser. Other browser information may vary slightly.

Example – Animating a Form Widget

In this example we will use JavaScript to animate a form widget in HTML page, based on user actions. This happens according to the following user events,

  1. User clicks ‘clear’, the widget entry is cleared completely
  2. User clicks ‘run’, we add 20 dots into the widget in addition to whatever is already present
  3. We delegate the animation code via the setInterval() callback which repeats a function every so-many, user specified, milli-seconds. We will add a ‘.’ every 1s, i.e. 1000ms.
  4. Once we reach 20dots on widget, we will disable the repetition function.Putting it all together we get the HTML + JavaScript code,
<html>
<head>
<script src="./jquery.js"></script>
<script type="text/javascript">
var init = function() {
   console.log("Init fcn");
};

var dot_data = {pos: 0, limit : 20};

var intervalID;

function reset_widget() {
  $("#widget").val(""); //clear wiget
}

function animate_widget( ) {
  if ( dot_data.pos < dot_data.limit ) {
    var newVal = $('#widget').val()+'.';
    $('#widget').val(newVal);
    dot_data.pos = dot_data.pos + 1;
    console.log("Running @ " + dot_data.pos );                       
  } else {
    clearInterval( intervalID );
  }
};

function start_animate_widget() {
  dot_data.pos = 0; //reset
  intervalID  = setInterval(animate_widget,1000);
};

</script>
</head>
<body onload="init();">
<input type="entry" id="widget"> </input>
<button onclick="javascript:start_animate_widget();" id="calcF2C">Run</button><BR />
<button onclick="javascript:reset_widget();" id="calcF2C">Clear</button><BR />
</body>
</html>

which you can run on the Google Chrome browser, click the ‘Run’ button on the form, and see the output. Looking at the console log, under ‘Menu > Tools > Developer Tools > JavaScript Console’, you get following output,

Init fcn 
Running @ 1 timeout.html:22
Running @ 2 timeout.html:22
Running @ 3 timeout.html:22
Running @ 4 timeout.html:22
Running @ 5 timeout.html:22
...
Running @ 10 timeout.html:22
...
Running @ 20 timeout.html:22

Also clicking the ‘Clear’ button eliminates the 20 dots.

Summary

Browser and JavaScript engine have to run simultaneously. Since there is no single concept of a sleep function, JavaScript offers a different model of delayed execution which uses the asynchronous calls setTimeout, setInterval functions in place of sleep. A simple neatly written client-side code in JavaScript goes a long way in helping usability. But also JavaScript is increasingly used in the backend via Node.js and other platforms.