Skip to content

Instantly share code, notes, and snippets.

@hns
Created June 7, 2011 07:46
Show Gist options
  • Save hns/1011847 to your computer and use it in GitHub Desktop.
Save hns/1011847 to your computer and use it in GitHub Desktop.
Async I/O pattern using JS generators and promises
// Pseudo code for a driver that enables doing asynchronous I/O using generators and promises.
// See the following URLs for actual code:
// https://github.com/hns/stick/blob/master/lib/stick/middleware/continuation.js
// https://github.com/hns/stick/blob/master/examples/continuation/app.js
// If app is a generator and yields promises, the result of those promises
// will be passed back into the generator as soon as they're resolved.
function handle(app, request) {
var response = app(request);
// check if response is a generator
if (response && typeof response.next === "function") {
response = response.next();
// check if generator yielded a promise
// see http://wiki.commonjs.org/wiki/Promises/A
if (response && typeof response.then === "function") {
var deferred = defer();
var handlePromise = function(p) {
p.then(
function(value) {
try {
var v = generator.send(value);
if (v && typeof v.then === "function") {
// generator returned a promise again
handlePromise(v);
} else {
// generator returned final value
deferred.resolve(v);
}
} catch (error) {
// generator threw an error
deferred.resolve(error, true);
}
},
function(error) {
// promise resolved to error
deferred.resolve(error, true);
generator.throw(error);
}
);
};
handlePromise(response);
return deferred.promise;
}
// todo: handle non-promise generator
}
return response;
}
// an application that does async I/O by yielding promises
function app(request) {
// yield a promise
var data = yield getDataAsPromise(request.someId);
// get more data yielding another promise
var moreData = yield getMoreDataAsPromise(data);
// return the final response
yield renderResponse(data, moreData);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment