Skip to content

Instantly share code, notes, and snippets.

@linktohack
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linktohack/d7184a0317d43f0f9c40 to your computer and use it in GitHub Desktop.
Save linktohack/d7184a0317d43f0f9c40 to your computer and use it in GitHub Desktop.
Promise in 50 lines of code
var Promise = (function() {
var Promise = function(callback) {
this._done = [];
this._fail = [];
this.state = 'pending';
this.value = undefined;
callback && callback(this.resolve.bind(this), this.reject.bind(this));
};
Promise.prototype = {
resolve: function(value) {
this.state = 'resolved';
this.value = value;
this._done.forEach(function(each) {
window.setTimeout(function() {
thenValue = each.callback(value);
if (thenValue && typeof thenValue.state === 'resolved') {
each.promise.resolve(thenValue.value)
}
else if (thenValue && typeof thenValue.state === 'rejected') {
each.promise.rejected(thenValue.value)
}
else if (thenValue && typeof thenValue.then === 'function') {
thenValue.then(each.promise.resolve.bind(each.promise),
each.promise.reject.bind(each.promise));
} else {
each.promise.resolve(thenValue);
}
});
});
return this;
},
reject: function(reason) {
this.state = 'rejected';
this.value = reason;
this._fail.forEach(function(each) {
window.setTimeout(function() {
thenValue = each.callback(reason);
if (thenValue && typeof thenValue.state === 'resolved') {
each.promise.resolve(thenValue.value)
}
else if (thenValue && typeof thenValue.state === 'rejected') {
each.promise.rejected(thenValue.value)
}
else if (thenValue && typeof thenValue.then === 'function') {
thenValue.then(each.promise.resolve.bind(each.promise),
each.promise.reject.bind(each.promise));
} else {
each.promise.reject(thenValue);
}
});
});
return this;
},
then: function(done, fail) {
var newPromise = new Promise();
switch (this.state) {
case 'pending':
done && this._done.push({ callback: done, promise: newPromise });
fail && this._fail.push({ callback: fail, promise: newPromise });
break;
case 'resolved':
newPromise.then(done, fail);
newPromise.resolve(this.value);
break;
case 'rejected':
newPromise.then(done, fail);
newPromise.reject(this.value);
}
return newPromise;
},
};
Promise.all = function(promises, values) {
promises = promises || [];
values = values || [];
var newPromise = new Promise();
var first = promises.pop();
if (first === undefined ) {
newPromise.resolve(values);
} else {
first.then(function(value) {
values.unshift(value);
Promise.all(promises, values).then(newPromise.resolve.bind(newPromise));
}, function(reason) {
newPromise.reject(reason);
});
}
return newPromise;
}
return Promise;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment