Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created June 5, 2020 17:30
Show Gist options
  • Save XoseLluis/af57dab37423e042c4c92bb324582efc to your computer and use it in GitHub Desktop.
Save XoseLluis/af57dab37423e042c4c92bb324582efc to your computer and use it in GitHub Desktop.
Lazy Promises
//we don't need to inherit from Promise, await works fine with just a "thenable"
//notice in the second part of the code that Promise.resolve of a thenable returns a new Promise rather than the thenable
class LazyPromise {
constructor(creationFn){
console.log("creating LazyPromise");
this.initialized = false;
this.creationFn = creationFn;
}
then(resFn, rejFn){
if (!this.initialized){
console.log("creating Real Promise");
this.initialized = true;
this.internalPromise = new Promise(this.creationFn);
}
return this.internalPromise.then(resFn, rejFn);
}
}
function sleep(ms){
let resolveFn;
let pr = new Promise(res => resolveFn = res);
setTimeout(() => resolveFn(), ms);
return pr;
}
(async () => {
let pr1 = new LazyPromise(res => {
console.log("starting query");
setTimeout(() => {
console.log("finishing query");
res("hi");
}, 2000);
});
console.log("before sleep");
await sleep(5000);
console.log("after sleep");
let result = await pr1;
console.log("promise returns: " + result);
let prA = new Promise(() => {});
let prB = Promise.resolve(prA);
console.log(prA === prB); //true
//LazyPromise is a thenable
prA = new LazyPromise(() => {});
prB = Promise.resolve(prA);
console.log(prA === prB); //false
let prC = new LazyPromise(res => {
console.log("starting query");
setTimeout(() => {
console.log("finishing query");
res("Bye");
}, 2000);
});
let prD = Promise.resolve(prC);
result = await prD;
console.log(result); //Bye
//as explained in MDN, it wraps the thenable in a new Promise, but this new promise is not resolved until the thenable is resolved
//the returned promise will "follow" that thenable, adopting its eventual state;
})();
class LazyPromise extends Promise{
constructor(creationFn){
//compiler forces me to do a super call
super(() => {});
console.log("creating LazyPromise");
this.initialized = false;
this.creationFn = creationFn;
}
then(resFn, rejFn){
if (!this.initialized){
console.log("creating Real Promise");
this.initialized = true;
this.internalPromise = new Promise(this.creationFn);
}
return this.internalPromise.then(resFn, rejFn);
}
}
function sleep(ms){
let resolveFn;
let pr = new Promise(res => resolveFn = res);
setTimeout(() => resolveFn(), ms);
return pr;
}
(async () => {
let pr1 = new LazyPromise(res => {
console.log("starting query");
setTimeout(() => {
console.log("finishing query");
res("hi");
}, 2000);
});
console.log("before sleep");
await sleep(5000);
console.log("after sleep");
let result = await pr1;
console.log("promise returns: " + result);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment