I've being working confortably with promise implementations for some time now.
So I've decided to implement my own promise library just for the fun (and learn something in the process too).
I'm trying to follow the Promise A+ specs (maybe I'll leave some details out, because I'm not meaning to make this a production code).
My full code (still in progress) is in this gist, but the relevant parts are bellow.
I'm facing a problem implementing then(). I simply don't know what to do when the promise is pending:
Promise.prototype.then = function(onFulfill, onReject) {
var ret;
var self = this;
if (isFulfilled.call(this)) {
console.log('fulfilled');
if (isFunction(onFulfill)) {
return promiseResolution(this, onFulfill(this.value));
} else {
return new Promise(function(resolve){
resolve(self.value);
});
}
} else if (isRejected.call(this)) {
console.log('rejected');
if (isFunction(onReject)) {
return promiseResolution(this, onReject(this.reason));
} else {
return new Promise(function(resolve, reject){
reject(self.reason);
});
}
} else if (isPending.call(this)) {
console.log('pending');
enqueueCallback(this.fulfillCallbackQueue, onFulfill);
enqueueCallback(this.rejectCallbackQueue, onReject);
// ... what now?
}
};
function promiseResolution(promise, x) {
if (promise === x) {
throw new TypeError('Cannot resolve promise with itself');
} else if (x instanceof Promise) {
if (isFulfilled.call(x)) {
return new Promise(function(resolve, reject){
resolve(x.value);
});
} else if (isRejected.call(x)) {
return new Promise(function(resolve, reject){
reject(x.reason);
});
} else {
return x;
}
} else {
return new Promise(function(resolve, reject){
resolve(x);
});
}
}
The answer must be quite obvious, but I'm kind of mind-blocked here.
I've updated the gist with the test suite I'm writing.
I was able to sucessfully run the tests for a first implementation. This is the git repository where I've stored my code. I'll try to keep improving it.
Thank's to @BenjaminGruenbaum.
First of all - make sure you're not implementing A+ unless you have a very good reason to do just that. It is very tricky to make a good promise implementation.
When the promise is pending - push the following to a handler array:
When the promise that returns the new promise undergoes resolution, you need to
resolve when it's done (reject if it threw). Check for the same reference on the return value. If there is no handler or it is not a function - you can pass e => { throw e; } instead.resolve when it's done (reject if it threw). Check for the same reference on the return value. If there is no handler or it is not a function - you can pass v => v instead.Of course, resolve itself needs to perform assimilation, as well as from foreign thenables. I recommend running against the promises/A+ test suite and work it out bit by bit until all tests pass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With