Skip to content

Instantly share code, notes, and snippets.

@PandaWhisperer
Last active August 29, 2015 14:10
Show Gist options
  • Save PandaWhisperer/153dbaae00f1f5598aed to your computer and use it in GitHub Desktop.
Save PandaWhisperer/153dbaae00f1f5598aed to your computer and use it in GitHub Desktop.
var Promise = require("bluebird");
/**
* Promised is a shim that wraps a collaborator that requires
* asynchronous initialization. Instead of having to wait for
* the initialization to finish (and do all your code that
* depends on it in a giant `.then()` call), you get an object
* you can use immediately.
*
* Every method invoked on it will simply return another promise
* that is fulfilled either
*
* a) when the collaborator has finished initializing
* b) immediately, if the collaborator is already available
*/
function Promised(promise) {
if (promise instanceof Promise) {
this.promised = promise;
} else {
throw new Error("must provide a promise!");
}
var methods = Array.prototype.slice.call(arguments, 1),
self = this;
methods.forEach(function(method) {
self[method] = self.exec.bind(self, method);
});
}
Promised.prototype.exec = function(/* varargs */) {
var args = Array.prototype.slice.call(arguments),
method = args.shift(), // first argument is method name
self = this;
function apply(obj, method, args) {
return obj[method].apply(obj, args);
}
if (this.promised instanceof Promise) {
return this.promised.then(function(obj) {
self.promised = obj;
return apply(obj, method, args);
});
} else {
try {
return Promise.resolve(apply(this.promised, method, args));
} catch (err) {
return Promise.reject(err);
}
}
}
module.exports = Promised;
var Promise = require("bluebird"),
Promised = require("./promised");
var promised = new Promised(Promise.resolve("test"));
// promises.exec() always returns a promise that
// resolves to the return value of the executed method
promised.exec("toUpperCase").then(console.log); // prints "FOO"
promised.exec("chatAt", 0).then(console.log); // prints "f"
// promise is rejected if method does not exist, or throws an error
promised.exec("doesntExist").catch(console.error); // prints "TypeError: Cannot call method 'apply' of undefined"
// Nicer version: use method shims
promised = new Promised(Promise.resolve("test"), "toUpperCase", "charAt");
// now you can do:
promised.toUpperCase().then(console.log); // prints "FOO"
promised.charAt(0).then(console.log); // prints "f"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment