Skip to content

Instantly share code, notes, and snippets.

@oliverfoster
Last active January 1, 2024 20:10
Show Gist options
  • Save oliverfoster/00897f4552cef64653ef14d8b26338a6 to your computer and use it in GitHub Desktop.
Save oliverfoster/00897f4552cef64653ef14d8b26338a6 to your computer and use it in GitHub Desktop.
Deferred promise
class DeferredPromise extends Promise {
constructor(def = (res, rej)=>{}) {
let res, rej;
super((resolve, reject)=>{
def(resolve, reject);
res = resolve;
rej = reject;
});
this.resolve = res;
this.reject = rej;
this.isCancelled = false;
}
cancel(err) {
this.isCancelled = true;
this.reject(err || new Error("Cancelled deferred promise."));
}
defer(task) {
this.task = task;
}
async execute(...args) {
if (!this.task) {
return this.reject(new Error("No task defined in deferred promise."));
}
try {
args.push(this);
const value = await this.task.call(this, ...args);
this.resolve(value);
} catch(err) {
this.reject(err);
}
}
}
module.exports = DeferredPromise;
@ctjlewis
Copy link

Incredibly cool with the def = (res, rej) => {} workaround.

@FaberM
Copy link

FaberM commented Dec 30, 2023

Wow, this is really close to what I came up with, but yours actually works 😂
However, I cannot understand why 🤔 Would you mind explaining why adding the def parameter to the constructor and calling it from within that function supplied to super actually works? 🙏

@oliverfoster
Copy link
Author

oliverfoster commented Jan 1, 2024

I believe, because I can't exactly remember, that the await keyword needs it, for some reason, perhaps transpiling through Babel requires it?

The easiest thing to do is to remove line 6 and the constructor default and see what happens.

I did once know but it was a while ago. Apologies.

@FaberM
Copy link

FaberM commented Jan 1, 2024

I totally understand, thanks for you time 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment