Skip to content

Instantly share code, notes, and snippets.

@tvcutsem
Created June 22, 2011 18:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tvcutsem/1040714 to your computer and use it in GitHub Desktop.
Save tvcutsem/1040714 to your computer and use it in GitHub Desktop.
Deferred functions in Javascript using Generators
<!DOCTYPE html>
<html>
<head>
<!-- using Kris Kowal's Q library, based on CommonJS Promises/B
https://github.com/kriskowal/q
http://wiki.commonjs.org/wiki/Promises/B
Code based on ideas by Mark S. Miller and Dave Herman. The animation example
was taken from <http://wiki.ecmascript.org/doku.php?id=strawman:deferred_functions>
-->
<script src="https://github.com/kriskowal/q/raw/master/q.js"></script>
<script type="application/javascript;version=1.7">
// deferred function(<params>) { <body> }
// ~~>
// Q.async(function*(<params>) { <body> });
//
// await <expr>
// ~~>
// yield <expr>
function isStopIteration(e) {
return Object.prototype.toString.call(e) === "[object StopIteration]";
}
Q.async = function(generatorFunc) {
return function asyncFunc(/*...args*/) {
var args = Array.prototype.slice.call(arguments);
const continuer = function(verb, valueOrErr) {
let awaited;
try {
awaited = generator[verb](valueOrErr);
} catch (e) {
if (isStopIteration(e)) { return Q.ref(e.value); }
return Q.reject(e);
}
return Q.when(Q.ref(awaited), callback, errback);
};
const generator = generatorFunc.apply(this, args);
const callback = continuer.bind(continuer, 'send');
const errback = continuer.bind(continuer, 'throw');
return callback(void 0);
};
};
function delay(millis, answer) {
const deferredResult = Q.defer();
setTimeout(function() { deferredResult.resolve(answer); }, millis);
return deferredResult.promise;
}
var deferredAnimate = Q.async(function(element) {
for (var i = 0; i < 100; ++i) {
element.style.marginLeft = ''+i+'px';
yield delay(20);
}
});
function test() {
Q.when(Q.ref(deferredAnimate(document.getElementById('box'))),
function() { alert('Done!'); });
}
</script>
</head>
<body onload="test()">
<div id="box" style="width: 20px; height: 20px; background-color: red;"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment