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:

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:

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:

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.

What is the fuss about strong typing really all about? JavaScript doesn't make much use of type so what is it missing? What is more difficult to do in JavaScript than in a typed language? Are there th [ ... ]

The prototype is about the most mysterious part of JavaScript. Once you have mastered the call context and the constructor, it is the prototype that you have to turn to. How does it work? How do you u [ ... ]