Example

In this example, we utilize native generator in JavaScript 1.7 to create continuations/coroutines. The Strands compiler will automatically compile the code for coroutine support in JavaScript environments that don't support JS 1.7. So this will run natively in Firefox 2+ and will be compiled for other browsers. We're going to create a simple animation that causes a button to move back and forth on command. To start off, we're going to create a sleep method that yields execution for a specified number of milliseconds:

sleep = strand(function(millis) {
	var future = new Future();
	setTimeout(future.fulfill, millis);
	yield future.result();
});
Now with our sleep method implemented, we're able to implement a generalized animation method that doesn't require callbacks:
animate = strand(function(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
		yield sleep(frameTime);
	}

	element.style[property] = endValue + "px";
});

In addition to animation and sleeping, we'll create a method that will yield until a DOM element has been clicked:
waitForClick = strand(function(element) {
	var future = new Future();
	element.onclick = future.fulfill;
	yield future.result();
});
Now we can use our animate and waitForClick methods to create an interactive animation that bounces a button back and forth on screen at the user's request:
run = strand(function() {
	var theButton = document.getElementById("theButton");
	while(true) {
		theButton.innerHTML = "go right";
		
		// move the button to the right (note the blocking operations)
		yield waitForClick(theButton);
		theButton.innerHTML = "-->";
		yield animate(theButton, "left", 200, 1000, 20);

		theButton.innerHTML = "go left";

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

We put all of the above code into one file, moveButton.js17. moveButton.js17 can run natively in Firefox 2+, debugging is a breeze, and the compiled code in IE looks a little scary, but keep in mind that even it is fairly unreadable, line numbering is consistent with the original source to help with the debugging process.

Finally, we need to whip up our HTML and JavaScript to load and compile moveButton.js:

    <button id="theButton" style="left:0px;"></button>
    <script src="../js/strands.js"></script>
    <script>strands.compilerUrl = '../js/compiler.js';strands.loadScript("moveButton.js17");<</script>

Here's the browser rendering of the above HTML and JavaScript:

The next section describes how to use Strands to compile JavaScript to support coroutines and threading.