So I wanted to extend Promise to have a 'progress' part so that i can report progrss with it while using Promise for my Async tasks.
Thus I extended Promise like this:
class promisePro extends Promise {
constructor(fn) {
super(function (resolve, reject) {
fn(resolve, reject, this._progress.bind(this));
});
}
_progress(v) {
if (this.progressCB)
this.progressCB(v);
}
progress(fn) {
this.progressCB = fn;
}
}
and used it:
function ptest() {
return new promisePro((resolve, reject, progress) => {
setTimeout(() => {
progress(0.3)
}, 1000)
setTimeout(() => {
progress(0.6)
}, 2000)
setTimeout(() => {
progress(0.9)
}, 3000)
setTimeout(() => {
resolve(1)
}, 4000)
})
}
and used itt:
ptest().then((r) => {
console.log('finiished: ' + r)
}).progress((p) => {
console.log('progress: ' + p)
})
and got this error:
ptest().then((r) => {
^
TypeError: Promise resolve or reject function is not callable
What am i doing wrong here?
I was using node 7.5, updated to 8.4. Got that error in both versions.
Thanks.
there are a couple of issues to look out for here.
firstly, the "this" keyword is undefined until the super function is called. therefore you could change the constructor to something like below, using a function to reference an instantiated variable to sel
constructor(fn) {
let self;
super(function (resolve, reject) {
fn(resolve, reject, value => self._progress(value));
});
self = this;
}
secondly, keep in mind you are extending the promise type, so when you are calling the "then" function on it, it will return a new promise object, not your new promise type, so the progress function is undefined there. a way to avoid this is to return "this" in the progress function, and in the usage to use the progress function before then, as below
progress(fn) {
this.progressCB = fn;
return this;
}
and for the usage
ptest().progress((p) => {
console.log('progress: ' + p)
}).then((r) => {
console.log('finiished: ' + r)
})
but now you will lose the benefit of the promise and won't be able to chain more promises with progress (still, depends on your use case).
As a suggestion for a different approach, have you tried using Observables? http://reactivex.io/rxjs/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With