Last active
September 8, 2020 20:26
-
-
Save XoseLluis/3892fa7f0f686fbb68640fac9bcb2a19 to your computer and use it in GitHub Desktop.
Experiment to implement Synchronous Inspection for Promises as the one provided by bluebird. Use Inheritance for it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Implement Synchronous Inspection like the one provided by bluebirdjs | |
//http://bluebirdjs.com/docs/api/synchronous-inspection.html | |
class SyncInspectPromise extends Promise{ | |
constructor(executorFn){ | |
//compiler forces me to do a super call | |
super(() => {}); | |
this._isFulfilled = false; | |
this._value = null; //resolution result | |
this._isRejected = false; | |
this._reason = null; //rejection reason | |
this._isPending = true; | |
//we need to be able to invoke the original resFn, rejFn functions after performing our additional logic | |
let origResFn, origRejFn; | |
this.internalPr = new Promise((resFn, rejFn) => { | |
origResFn = resFn; | |
origRejFn = rejFn; | |
}); | |
let overriddenResFn = (value) => { | |
this._isPending = false; | |
this._isFulfilled = true; | |
this._value = value; | |
origResFn(value); | |
}; | |
let overriddenRejFn = (reason) => { | |
this._isPending = false; | |
this._isRejected = true; | |
this._reason = reason; | |
origRejFn(reason); | |
}; | |
executorFn(overriddenResFn, overriddenRejFn); | |
} | |
isFulfilled(){ | |
return this._isFulfilled; | |
} | |
getValue(){ | |
return this.isFulfilled() | |
? this._value | |
: (() => {throw new Error("Unfulfilled Promise");})(); //emulate "throw expressions" | |
} | |
isRejected(){ | |
return this._isRejected; | |
} | |
getReason(){ | |
return this.isRejected() | |
? this._reason | |
: (() => {throw new Error("Unrejected Promise");})(); //emulate "throw expressions" | |
} | |
isPending(){ | |
return this._isPending; | |
} | |
then(fn){ | |
//we set the continuation to the internal Promise, so that invoking the original res function | |
//will invoke the continuation | |
return this.internalPr.then(fn); | |
} | |
catch(fn){ | |
//we set the continuation to the internal Promise, so that invoking the original rej function | |
//will invoke the continuation | |
return this.internalPr.catch(fn); | |
} | |
finally(fn){ | |
return this.internalPr.finally(fn); | |
} | |
} | |
function sleep(ms){ | |
let resolveFn; | |
let pr = new Promise(res => resolveFn = res); | |
setTimeout(() => resolveFn(), ms); | |
return pr; | |
} | |
function printValueIfFulfilled(pr){ | |
if (pr.isFulfilled()){ | |
console.log("Promise resolved to: " + pr.getValue()); | |
} | |
else{ | |
console.log("Promise NOT resolved yet"); | |
} | |
} | |
(async () => { | |
let pr1 = new SyncInspectPromise(res => { | |
console.log("starting query"); | |
setTimeout(() => { | |
console.log("finishing query"); | |
res("hi"); | |
}, 3000); | |
}); | |
console.log("isPending: " + pr1.isPending()); | |
//this fn runs in 1 seconds (while the async fn takes 3 seconds) so it won't be fulfilled at that point) | |
setTimeout(() => printValueIfFulfilled(pr1), 1000); | |
let result = await pr1; | |
console.log("result value: " + result); | |
printValueIfFulfilled(pr1); | |
})(); | |
//output: | |
// starting query | |
// isPending: true | |
// Promise NOT resolved yet | |
// finishing query | |
// result value: hi | |
// Promise resolved to: hi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment