0.0.6 • Published 8 years ago

promise-class v0.0.6

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

promise-class Build Status

easy promises, coroutines, and a few other goodies!

  • by having a $deferred argument in a method you now have a function that returns a promise.
  • by having a $deferred argument in a generator method its now a coroutine

promise-class is the new promise-object

coroutines in PromiseClass are 15x faster than PromiseObject ;)

requirements

you must be using at minimum node 5.0.0

usage

here is an example class that looks up information on a user

var PromiseClass = require('promise-class');
var database = ...;

PromiseClass(class User {
	static *find ($deferred, id) {
		$deferred.resolve({
        	details: yield this.getDetails(id),
            friends: yield this.getFriends(id)
        });
    }
    
    static *getDetails($deferred, id) {
    	$deferred.resolve(yield database.query(...));
    }
    
    static *getFriends($deferred, id) {
    	$deferred.resolve(yield database.query(...));
    }
});

PromiseClass.wrap(function *() {
	var user = yield User.find(123);
})();

installation

npm install promise-class
node --harmony script.js

native promises?

by default PromiseClass will use BlueBird for promises if its in your node_modules directory.

if you would like to use another Promise library you can do the following

PromiseClass.setPromise(Q);

pseudo params

there are a few rules with these params

  • if you want to use $deferred it MUST be the first param
  • any other pseudo param must be before any real params

these pseudo params are supported

  • $deferred converts the method into a deferred method
  • $class returns the class
  • $self alternative to var self = this;
  • $*config, $*settings, $*options ensures that the first argument is an object

$*config / $*settings / $*options

helper that makes working with $config objects a little easier

PromiseClass(class User {
	constructor ($config) {
		this._name = $config.name;
    }
});

new User({name: 'joe'});
new User(); // this does not error out because the argument was replaced with an empty object

this would allow you to call the class method via Class.method

$deferred / promises

promoise-object is promise library agnostic, you initialize the wrapper by passing in the promise library you are using.

below is an example of using promises and showing errors

PromiseClass(class User {
	constructor (name) {
    	this._name = name;
    }
    
    getInfo ($deferred, error) {
		setTimeout(function () {
			if (error) {
				$deferred.reject(new Error('Something went wrong'));
			} else {
				$deferred.resolve({age: 12});
			}
		}, 1000);
	}
});

PromiseClass.wrap(function * {
	var joe = new User('joe');
    
	yield joe.getInfo(false);
    
    try {
    	joe.getInfo(true);
    } catch (error) {
    	console.log(error);
    }
})();

coroutines

any method that is a generator, and has the $deferred argument automatically becomes a coroutine

  *getInfo ($deferred) {
      var one = yield this.getSomething();
      $deferred.resolve(one);
  }

reopen

you can add methods to an instance by passing them via .reopen like this

var user = new User();

user.reopen({
	*getName ($deferred, $self) {
		setTimeout(function () {
			$deferred.resolve($self._name);
		}, 1000);
	}
});

and you can add methods to a class like this

User.reopen({
	*getName ($deferred, $self) {
		setTimeout(function () {
			$deferred.resolve($self._name);
		}, 1000);
	}
});

when you should not reopen and override existing methods because you cant use super

mixins

var Mixin =  {
	getRandomNumber () {
		return Math.random();
	}
};

var Mixin2 = {
	getRandomNumberDeferred ($deferred) {
		$deferred.resolve(Math.random());
	},
    
    *getRandomNumberCoroutine ($deferred) {
    	yield this.getRandomNumberDeferred();
	}
};

PromiseClass(class Class {
}, Mixin, Mixin2);

// examples
var example = new Class();

example.getRandomNumber();

example.getRandomNumberDeferred().then(function (number) {
	console.log(number);
});

example.getRandomNumberCoroutine().then(function (number) {
	console.log(number);
});

mixins should only use initialize to store instance vars

var Mixin =  {
	initialize () {
		this._tags = [];
	},
    
    get length () {
    	return this._tags.length;
    },

	hasTag (tag) {
		return this._tags.indexOf(tag) !== -1;
	},

	addTag (tag) {
		if (this.hasTag(tag)) return;

		this._tags.push(tag);
	}
};

anonymous classes

by default PromiseClasses are global in your file (not app), you can change this by doing the following

var User = PromiseClass.anonymous(class User {
});

or

var User = PromiseClass.anonymous(class {
});

wrap

Convience method for creating a coroutine

var getUser = PromiseClass.wrap(function *(id) {
	var user = yield getUser(id);
	...
	return user;
});

getUser(123).then(function (user) {
	console.log(user);
});

Or

var users = yield BlueBird.map(userIds, PromiseClass.wrap(function *(id) {
	var user = yield getUser(id);
	...
	return user;
}));
0.0.6

8 years ago

0.0.5

8 years ago

0.0.4

9 years ago

0.0.3

9 years ago

0.0.2

9 years ago

0.0.1

9 years ago