Task.js Asynchronous Tasks In JavaScript
Written by Mike James   
Monday, 06 May 2013
Article Index
Task.js Asynchronous Tasks In JavaScript
A First Example

 

A First Example

Let's take a look at a very simple example of an asychronous task  using jQuery and its ajax method to load a file of data.

task.spawn(function() {
 var data = yield $.ajax("text.html");
 $('#result').html(data);
});

All of the Task.js methods are within the task namespace. 

The spawn function adds the task to the scheduler and starts runing it.  The first instruction:

var data = yield $.ajax(url);

Uses the jQuery ajax method to download an HTML file. The ajax method returns a promise and the value of the promise is the content of the file.

The yield returns control to the scheduler which stores the Promise and looks to see if there is another Task ready to run. If there is then it runs it, if not it releases the UI thread. At some point the Promise resolves and its onResolve function is called. This reactivates the scheduler which unpacks the Promise's value and sends it off to the the yield using send(value).  

This may sound complicated and it is only rough outline of what happens but the net effect is that the ajax call is performed asynchronously without blocking the UI or any other task and the contents of the file is stored in the data variable. 

This looks to the programmer just as if ajax was a synchronous blocking method.

Notice that the user hasn't had to worry about Promises, call backs or anything else. You can also fade in a message when the data has been loaded:

var status = $('#status').hide().html('Download complete.');
yield status.fadeIn().promise();

The reason that this is interesting is that many of the jQuery methods that you already know are equiped to return a promise object if you ask for it.  The fadeIn method has been able to  return a Promise object since jQuery 1.6 although it isn't often used because it seems complicated. Used with Task.js it makes it seem easy to wait for the fadeIn to complete without blocking the UI thread. Notice that in there is no value returned by the Promise in this case so we don't make use of it.

The Thread Hogging Loop

Perhaps the most interesting thing about Task.js is that it makes it possible to write "tight" loops that in standard JavaScript would bring the system to a halt. 

For example, if you write:

var i=0 while(true){
 console.log(i);
 i=i+1
}

Then what happens it that the UI freezes and you don't see any values displayed in the log. 

This is a common beginners mistake but with the help of Task.js this tight loop need no longer be avoided. All you have to do is yield now and again so that other tasks have the opertunity to do some work:

task.spawn( function() {
  var i=0
  while(true){
   console.log(i);
   i=i+1
   yield task.sleep(1000);
  }
});

Now everything works as expected and you will see the values appear in the console and the UI remains active as well as any other tasks you might have started running. The sleep method simply puts the task to sleep for 1000 milliseconds and the scheduler runs other tasks during this period. 

You can also use the sleep method to demonstrate the operation of two tasks:

task.spawn(function() {
 var i=0 while(true){
  console.log("A");
  i=i+1; 
  yield task.sleep(100);
 }
});
task.spawn(function() {
 var i=0 while(true){
  console.log("B");
  i=i+1;
  yield task.sleep(1000);

 }
}); 

The first task prints an A every tenth of a second and the second task prints B every second. If you run the program you will see As and Bs interleaved in the log with ten times more As than Bs.

The Future

Of course you can't use this sort of approach at all widely until yield is better supported. There are ways of achieving the same results but none quite as elegant as using Task.js - it is a clever use of a facility introduced for one purpose for another. 

If you look at the Task.js documentation then you will find that there are lots of additional methods and facilities for managing tasks - most you will never need to use. 

The one requirement to make Task.js useful in the future is the use of the Promise object by asychronous methods. This is yet another good reason, if you needed one, for using Promises within your own asychronous routines.

Related Articles

jQuery, Promises & Deferred

jQuery Promises, Deferred & WebWorkers

 

To be informed about new articles on I Programmer, subscribe to the RSS feed, follow us on Google+Twitter, Linkedin or Facebook, install the I Programmer Toolbar or sign up for our weekly newsletter.

 

espbook

 

Comments




or email your comment to: comments@i-programmer.info

 

Banner


JavaScript Canvas - Fetch API

Working with lower-level data is very much part of graphics. This extract from Ian Elliot's book on JavaScript Graphics looks at how to use typed arrays to access graphic data.



JavaScript Jems - The Inheritance Tax

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, it doesn't do inheritance  [ ... ]


Other Articles

 



Last Updated ( Tuesday, 15 October 2013 )