使用 extends 对内置 Promise 进行子类化

Ben*_*Ben 5 javascript promise cancellation ecmascript-6 es6-class

我想向内置cancel的子类添加一个方法。Promise为什么这不起作用?

class CancellablePromise extends Promise {
    constructor(executor) {
        let cancel = null
        super((resolve,reject) => {
            cancel = reject
            executor(resolve, reject)
        })
        this.cancel = cancel
    }
}

const p = new CancellablePromise((resolve) => setTimeout(resolve, 1000))
    .then(() => console.log('success'))
    .catch((err) => console.log('rejected', err))

p.cancel() // Uncaught exception
Run Code Online (Sandbox Code Playgroud)

答案是 todo 吗Symbol.species

T.J*_*der 5

问题是thencatch、 和finally创建并返回一个新的Promise,而它们创建和返回的新 Promise 没有cancel该方法。

要解决这个问题,您必须重写,then以便它cancel从当前实例复制到新实例:

class CancellablePromise extends Promise {
    constructor(executor) {
        let cancel = null;
        super((resolve,reject) => {
            cancel = reject;
            executor(resolve, reject);
        });
        this.cancel = cancel;
    }

    then(onFulfilled, onRejected) {
        const p = super.then(onFulfilled, onRejected);
        p.cancel = this.cancel;
        return p;
    }
}

const p = new CancellablePromise((resolve) => setTimeout(resolve, 1000))
    .then(() => console.log('success'))
    .catch((err) => console.log('rejected', err));

p.cancel();
Run Code Online (Sandbox Code Playgroud)

您不需要执行catchor finally,它们都是使用调用来定义的then(根据规范)。

我应该指出,可取消的承诺有很多细微差别,我还没有详细讨论。Domenic Denicola 的旧版(现已撤回)可撤销承诺提案以及Ben Lesh 的这篇文章可能值得深入阅读。