Yesterday I wanted to answer with some elegant code to a question: "how can we abort Promises?"
// it's as easy as ... oh, wait, WUT?
class Disposable extends Promise {
constructor(callback, {signal}) {
super((resolve, reject) => {
signal.addEventListener('abort', reject);
callback(resolve, reject);
});
}
}
The idea was to use AbortController:
const controller = new AbortController();
new Disposable(
(resolve, reject) => {
setTimeout(resolve, 1000, 'OK');
},
controller
)
.then(console.log)
.catch(console.error);
// abort before Promise is resolved
setTimeout(() => controller.abort(), 500);
The issue is that as soon as new Disposable(...).then(...)
happens:
VM261:3 Uncaught TypeError: Cannot destructure property 'signal' of 'undefined' as it is undefined.
I thought it was an issue with the AbortController itself but it looks like even the simplest new Disposable(Object, {signal: 123}).then(console.log)
, removing the addEventListener
part, fails.
On the other hand, this works like a charm but it doesn't brand the Promise:
function Disposable(callback, {signal}) {
return new Promise((resolve, reject) => {
signal.addEventListener('abort', reject);
callback(resolve, reject);
});
}
Can anyone please explain why Promise cannot be extended with ease like any other builtin class?
Thank you!