Created
June 22, 2011 18:08
-
-
Save tvcutsem/1040714 to your computer and use it in GitHub Desktop.
Deferred functions in Javascript using Generators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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