However I got to thinking it doesn't actually depend on most of what people use promises for in the status quo of going through contortions to avoid CPS-converting all your javascript programs. (As an aside, much as I find js comfortable for some bizarre reason given my academic upbringing, I gotta say, it seems pretty ludicrous at times to actually do "the node.js thing" with code. Direct-style 4 lief.) Specifically the .then-chaining that a typical library like Q provides doesn't seem necessary for the promises that get yielded across coroutines.
Seems like I can just do the following: (in a recent firefox or chrome after you go into about:flags and turn on "experimental javascript features" or node 0.11.6 with the --harmony flag)
function Prom() { var self = this; this.then = function(k) { self.reso = function(x) { k(x); }; }; this.reso = function(x) { self.then = function(k) { k(x); }; }; } function spawn(task) { var gen = task(); (function go(x) { var s = gen.next(x); if (!s.done) s.value.then(go); })(); } function slow(v, t) { var p = new Prom(); setTimeout(function() { p.reso(v); }, t); return p; } spawn(function*() { var counter = 10; while(counter--) { var x = yield slow("a", 59); console.log(x); } }); spawn(function*() { var counter = 10; while(counter--) { var x = yield slow("b", 100); console.log(x); } });
(and here's the ocaml I wrote just to keep the types straight in my head:
let prom () = let rec reso = ref (fun x -> next := fun k -> k x); and next = ref (fun k -> reso := fun x -> k x) in (reso, next);;)