|Written by Mike James|
|Monday, 06 May 2013|
Page 1 of 2
The best that is currently on offer is the Promise or the Deferred object in jQuery. This allows asychronous functions to return a Promise object immediately and for the client to code to specify the function to run when the Promise resolves.
This is an improvement on the basic callback mechanism but it still makes a bit of a mess of the natural layout of the code and it can produces a nested mess if you need to have multiple Promises.
First let's take a look a the idea of a generator - yield and send.
If you haven't encountered the generator idea it is fairly simple.
If you write
in a function it becomes a generator.
If you call the function it returns an iterator object which has a next method.
Each time you call the next method the iterator executes the code of the original function until it encounters a yield when it halts and returns the value. When the next method is called again the execution begins at the instruction following the yield. The yield mechanism is a simple form of continuation.
and so on.
The calling routine can also send a return result to a yield by using the generators send method. If you use
in place of next() then the yield returns zero:
stores zero in answer. Notice that if the calling routine uses next to resume after the yield then answer is set to undefined - something not very clear from the documentation.
In normal use the send method is used to reset or modify the sequence that the generator produces, but Task.js uses it for a completely different purpose.
To see a generator in action as it was intended to be used the almost standard example is to create a Fibbonaci generator.
First to make any of the following work you have to be using Firefox and you have to load the script using:
Following this you can use yield:
Once defined you can use it to iterate through the Fibbonaci numbers:
which prints 0,1,1,2,3 and so on.
If you want to allow the caller to reset the generator you can do it something like:
and call it as;
So far we have seen the standard use of yield. What Task.js does is to take the yield statement and use it to implement not an iterator but a co-operative task interrupt.
The idea is that you write a function which yields each time it wants, or needs, to allow something else to happen. The clever part is that it yields a Promise object, which the scheduler uses to restart your function flowing the yield when the Promise resolves.
So the pattern used by Task.js is:
Your function runs until it reaches a point where it needs to wait for some asychronous operation or because it wants to give some other task a chance to run.
At this point is yields on an operation that returns a Promise that is resolved when the operation is complete.
The scheduler receives the Promise object and starts another Task or relinquishes the UI thread so that events can be processed.
When Promise object is resolved the task that blocked on it is restarted using its send(value) method. The causes result or value of the promise is returned as the value of the yield.
That's all there is to it and it is very simple.
The real beauty of this approach is that when you just look at the code you have to write it looks very simple even if there is a lot going on behind the scenes.
To make Task.js work you have to load it so include:
Now you can start to work with Task.js but remember to start your scripts with:
|Last Updated ( Tuesday, 15 October 2013 )|