javascript – 扩展承诺以支持进度报告

因此,我想扩展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/

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...