Skip to content

Instantly share code, notes, and snippets.

@pgarciacamou
Last active March 18, 2016 23:46
Show Gist options
  • Save pgarciacamou/22e048a878af78d4fcc7 to your computer and use it in GitHub Desktop.
Save pgarciacamou/22e048a878af78d4fcc7 to your computer and use it in GitHub Desktop.
MyPromise.js is a very, very light (778 Bytes) version of a Promise. It aims for performance rather than complexity or functionality.
export default class MyPromise {
constructor (fn) {
this._callbacks = [];
this._done = false;
if(fn) fn(this.fulfill.bind(this));
}
static all(promises) {
return new MyPromise(function (fulfill){
var counter = promises.length;
var results = [];
promises.forEach(function (promise){
promise.then(function (res){
results.push(res);
if(--counter === 0) fulfill(results);
});
});
});
}
fulfill(res) {
this._done = true;
if(res) this._res = res;
while(this._callbacks.length > 0){
this._callbacks.shift()(res);
}
return this;
}
then(callback) {
if(this._done) callback(this._res);
else this._callbacks.push(callback);
return this;
}
}
// author: Pablo G.
function MyPromise(fn){
this._callbacks = [];
this._done = false;
if(fn) fn(this.fulfill.bind(this));
}
MyPromise.all = function (promises){
return new MyPromise(function (fulfill){
var counter = promises.length;
var results = [];
promises.forEach(function (promise){
promise.then(function (res){
results.push(res);
if(--counter === 0) fulfill(results);
});
});
});
};
MyPromise.prototype.fulfill = function (res){
this._done = true;
if(res) this._res = res;
while(this._callbacks.length > 0){
this._callbacks.shift()(res);
}
return this;
};
MyPromise.prototype.then = function (callback){
if(this._done) callback(this._res);
else this._callbacks.push(callback);
return this;
};
function MyPromise(t){this._callbacks=[],this._done=!1,t&&t(this.fulfill.bind(this))}MyPromise.all=function(t){return new MyPromise(function(i){var s=t.length,n=[];t.forEach(function(t){t.then(function(t){n.push(t),0===--s&&i(n)})})})},MyPromise.prototype.fulfill=function(t){for(this._done=!0,t&&(this._res=t);this._callbacks.length>0;)this._callbacks.shift()(t);return this},MyPromise.prototype.then=function(t){return this._done?t(this._res):this._callbacks.push(t),this};
import _Promise from 'path/to/file';
describe('My Promise module.', function() {
var promise;
beforeEach(function() {
promise = new _Promise(function (fulfill) {
fulfill("promise");
});
});
it('should work synchronously', function() {
var result;
promise.then(function (res) {
result = res;
});
expect(result).toEqual("promise");
});
it('should work asynchronously', function(done) {
var result = "promise";
var promise = new _Promise(function (fulfill) {
setTimeout(function () {
fulfill(result);
}, 1);
})
promise.then(function (res) {
expect(res).toEqual(result);
done();
});
});
it('should not fulfill synchronously when asynchronous', function() {
var result;
var promise = new _Promise(function (fulfill) {
setTimeout(function () {
fulfill("promise");
}, 1);
})
promise.then(function (res) {
result = res;
});
expect(result).not.toEqual("promise");
});
it('should stay fulfilled', function(done) {
expect(promise._done).toBeTruthy();
setTimeout(function () {
promise.then(function (res1) {
setTimeout(function () {
promise.then(function (res2) {
expect(res1).toEqual(res2);
done();
});
}, 1);
});
}, 1);
});
it('should execute synchronously after being fulfilled', function() {
expect(promise._done).toBeTruthy();
var result;
promise.then(function (res) {
result = res;
});
expect(result).toBeTruthy("promise");
});
it('should implement "Chainable Methods Pattern"', function() {
new _Promise(function (fulfill) {
fulfill("chainable");
})
.then(function (res) {
expect(res).toEqual("chainable");
});
_Promise
.all([
new _Promise(function (fulfill) {
fulfill("chainable-1");
}),
new _Promise(function (fulfill) {
fulfill("chainable-2");
})
])
.then(function (resArray) {
expect(resArray[0]).toEqual("chainable-1");
expect(resArray[1]).toEqual("chainable-2");
});
});
describe('How to reject a promise.', function() {
it('should be very flexible v1', function() {
function handleError(e) {
expect(e).toBeTruthy();
}
new _Promise(function (fulfill) {
fulfill(new Error("my error"));
})
.then(function (res) {
if(res instanceof Error) return handleError(true);
fail("an error was expected");
});
});
it('should be very flexible v2', function() {
function handleError(e) {
if(e === 404) return true;
}
new _Promise(function (fulfill) {
fulfill(404);
})
.then(function (res) {
var err = handleError(res);
if(!err) fail("an error was expected");
expect(err).toBeTruthy();
});
});
});
});
@pgarciacamou
Copy link
Author

This Promise was created because we needed the ability to increase the speed of the algorithms used.

@pgarciacamou
Copy link
Author

I added unit tests with jasmine to show "how to use it"

@pgarciacamou
Copy link
Author

added a minified version of 0.28KB (287Bytes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment