因此,我想扩展Promise以获得“进度”部分,以便我可以使用Promise为我的异步任务报告它的进度.
因此我像这样扩展了Promise:
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;
}
}
并使用它:
function ptest() {
return new promisePro((resolve,progress) => {
setTimeout(() => {
progress(0.3)
},1000)
setTimeout(() => {
progress(0.6)
},2000)
setTimeout(() => {
progress(0.9)
},3000)
setTimeout(() => {
resolve(1)
},4000)
})
}
并使用itt:
ptest().then((r) => {
console.log('finiished: ' + r)
}).progress((p) => {
console.log('progress: ' + p)
})
并得到此错误:
ptest().then((r) => {
^
TypeError: Promise resolve or reject function is not callable
我在这做错了什么?
我使用的是节点7.5,更新到8.4.两个版本都有错误.
谢谢.
最佳答案
这里有一些值得关注的问题.
首先,在调用超级函数之前,“this”关键字是未定义的.因此,您可以将构造函数更改为类似下面的内容,使用函数将实例化变量引用到sel
constructor(fn) {
let self;
super(function (resolve,reject) {
fn(resolve,value => self._progress(value));
});
self = this;
}
其次,请记住,您正在扩展promise类型,因此当您在其上调用“then”函数时,它将返回一个新的promise对象,而不是新的promise类型,因此progress函数在那里是未定义的.一种避免这种情况的方法是在进度函数中返回“this”,并在使用之前使用进度函数,如下所示
progress(fn) {
this.progressCB = fn;
return this;
}
并用于使用
ptest().progress((p) => {
console.log('progress: ' + p)
}).then((r) => {
console.log('finiished: ' + r)
})
但是现在你将失去承诺的好处,并且无法通过进步链接更多的承诺(仍然取决于你的用例).
作为对不同方法的建议,您是否尝试过使用Observables?
http://reactivex.io/rxjs/