Wednesday, July 18th, 2007

JavaScript Strands: Adding Futures to JavaScript

Category: JavaScript, Library

Kris Zyp has released a framework built on Narrative JavaScript called JavaScript Strands.

Strands adds continuation-like coroutine and cooperative threading support to JavaScript to enable blocking capabilities for asynchronous event callbacks. This makes code that utilizes asynchronous operations much more linear, readable, and manageable.

Example Application

The following code allows for an animated button that moves right and left based on the click:

function sleep(millis) {
var future = new Future();
setTimeout(future.fulfill, millis);
future.result();
}

function animate(element, property, endValue, duration, frameTime) {
// calculate animation variables
var frameCount = Math.ceil(duration/frameTime);
var startValue = parseInt(element.style[property], 10);
var distance = endValue – startValue;
var jumpSize = Math.ceil(distance/frameCount);

// do the animation
for (var i = 0; i < frameCount - 1; i++) { var nextValue = startValue + (jumpSize * i); element.style[property] = nextValue + "px"; // note the yielding operation sleep(frameTime); } element.style[property] = endValue + "px"; } function waitForClick(element) { var future = new Future(); element.onclick = future.fulfill; future.result(); } function run() { var theButton = document.getElementById("theButton"); while(true) { theButton.innerHTML = "go right"; // move the button to the right (note the blocking operations) waitForClick(theButton); theButton.innerHTML = "-->“;
animate(theButton, “left”, 200, 1000, 20);

theButton.innerHTML = “go left”;

// move the button to the left (again note the blocking operations)
waitForClick(theButton);
theButton.innerHTML = “< --"; animate(theButton, "left", 0, 1000, 20); } } new Future(run); [/javascript]

Posted by Dion Almaer at 7:54 am
10 Comments

++---
2.9 rating from 47 votes

10 Comments »

Comments feed TrackBack URI

JavaScript is great at being an event driven language, if you can’t handle that and would rather use some convoluted solution such as this, then fine waste your time. Why not change careers first.

Comment by Todd — July 18, 2007

Strands is not intended to eradicate event driven techniques, but allows implementation encapsulation when operations involve asynchronous actions within the flow of code. Encapsulation of waiting for a DOM event is not a frequent use case (it’s just easy to make an example for understanding futures), but more frequent is encapsulating Ajax calls so you can write an (asynchronous) Ajax request without having to provide a callback for post-response execution:

var content = strands.request(url);

This functions blocks until the request is finished and returns the result. Simple encapsulated Ajax calls.

Comment by Kris Zyp — July 18, 2007

what i don’t like about this is inventing a proprietary extension to the javascript language. in my opinion you should stick to the native javascript capabilities instead of using an extension that requires to be “compiled” / converted to standard javascript.

Comment by Harald — July 18, 2007

Yes, compilation is certainly the biggest drawback to this approach. That is why we have built several different approaches for easing the compilation process. However, the precompiled code does not have any proprietary extensions. It is normal standard JavaScript, no special syntax required. The precompiled code just can’t suspend execution, and the compiled code can. Everything else is preserved.

Comment by Kris Zyp — July 18, 2007

Hi Kris, while I think it’s a good first effort, I’d like to see more of a standards based approach. Including custom operators as Neils Narrative JS does, and I see Strands adds to?, as I see it forces the developer to write in a non-standard manner producing code that is only useful in Narrative JS/Strands environments. Alternatively, as Neil has shown whats possible by using generators with his “Threading” aka trampolining example, I’d prefer an approach that went in this direction and used a translator to generate backwards compatible source for older JS implementations. Such that you write in the current(or your chosen feature set) ECMAScript spec and translate to the old. In the process testing for JS capability in browser just as most of the Ajax libraries do now for functionality and including the appropriate translated or raw library. Thereby gaining the benefits of new ECMAScript language features, and performance(code execution and file size aka bandwidth), automatically as browser manufacturers upgrade implementations. I’m not sure about how difficult debugging using this approach would be though.
Just my 2c.

Comment by Craig Overend — July 19, 2007

Craig,
Strands does use a more standards based approach than Narrative in the sense that that code can written using standard pure JavaScript rather than requiring a custom operator as Narrative does.
I will also soon have a version of Strands that does work on uncompiled generator-style yielding code like Neil’s 1.7 threading library (with improvements). However, the problem with writing 1.7 code is than you have to use browser detection to deliver js files. Is this better than one compilation that works for all browsers?

Comment by Kris Zyp — July 19, 2007

Todd,

How would you rewrite the animate() function above, using events instead of sleep()? And how would functions that call it handle the obvious synchronisation issues?

Comment by Tim Cooijmans — July 20, 2007

Tim, go to google search for ajax tutorials, they use callback methods and people have been using them with great success….

Comment by Todd — July 20, 2007

Threading in JS, genius! It’s like having the nicest lawnmower on your street, but you live in an apartment building, and have no grass.

Comment by Dan — July 20, 2007

Todd,

If you make one function use a callback method, the functions that call it have to be broken up too. It breaks abstraction, and I don’t know why any one would be happy with that.

A workaround would be to use callbacks for _every_ function call, as I have mentioned here before, but someone (“ix” IIRC) talked of using DOM events for the purpose. I thought you were talking about the same thing, but alas.

Comment by Tim Cooijmans — July 24, 2007

Leave a comment

You must be logged in to post a comment.