Skip to content

Instantly share code, notes, and snippets.

@ben-bradley
Created January 13, 2015 16:42
Show Gist options
  • Save ben-bradley/cc248e08ce9e8a7afcad to your computer and use it in GitHub Desktop.
Save ben-bradley/cc248e08ce9e8a7afcad to your computer and use it in GitHub Desktop.
A compilation of various promise generator controllers
// http://pag.forbeslindesay.co.uk/#/22
//
function async(makeGenerator){
return function (){
var generator = makeGenerator.apply(this, arguments)
function handle(result){ // { done: [Boolean], value: [Object] }
if (result.done) return result.value
return result.value.then(function (res){
return handle(generator.next(res))
}, function (err){
return handle(generator.throw(err))
})
}
return handle(generator.next())
}
}
var readJSON = async(function *(filename){
return JSON.parse(yield readFile(filename, 'utf8'))
})
function readFile(filename, enc){
return new Promise(function (fulfill, reject){
fs.readFile(filename, enc, function (err, res){
if (err) reject(err)
else fullfill(res)
})
})
}
var get = async(function *(){
var left = yield readJSON('left.json')
var right = yield readJSON('right.json')
return { left: left, right: right }
})
// https://gist.github.com/creationix/5761021
//
function run(generator) {
var iterator = generator(resume);
var data = null, yielded = false;
iterator.next();
yielded = true;
check();
function check() {
while (data && yielded) {
var err = data[0], item = data[1];
data = null;
yielded = false;
if (err) return iterator.throw(err);
iterator.send(item);
yielded = true;
}
}
function resume() {
data = arguments;
check();
}
}
run(function*(resume) {
console.log("Hello");
yield setTimeout(resume, 1000);
console.log("World");
});
// http://blogs.atlassian.com/2013/11/harmony-generators-and-promises-for-node-js-async-fun-and-profit/
//
var Q = require("q");
var ourSpawn = function(generatorFn) {
var gen = generatorFn();
// This method will get called over and over to keep pumping fulfilled
// promise values back into the generator.
var pumpGenerator = function(val) {
var ret = gen.next(val);
if(ret.done) {
// Generator has completed. We're done here.
return;
}
// Calling Q like this just wraps whatever the generator gave us back
// in a promise, if it wasn't already a promise.
var result = Q(ret.value);
result.then(function(val) {
// The promise that was yielded to us has completed. Pass it back
// into the generator and get ready for another round of fun.
pumpGenerator(val);
});
};
pumpGenerator();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment