Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Last active September 8, 2020 20:26
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 XoseLluis/3892fa7f0f686fbb68640fac9bcb2a19 to your computer and use it in GitHub Desktop.
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.
//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