Typescript:Promise的子类/扩展提供' TypeError:undefined不是一个承诺'在运行时间

时间:2017-04-14 22:46:40

标签: typescript promise typescript2.1

我试图取消打字稿中的async方法调用。

为此,我创建了一个新的Promise类型,它继承自Promise

class CancelablePromise<T> extends Promise<T>{

    public cancelMethod: () => void;
    constructor(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) {
        super(executor);
        // Set the prototype explicitly.

        Object.setPrototypeOf(this, CancelablePromise.prototype);

    }

    //cancel the operation
    public cancel() {
        if (this.cancelMethod) {
            this.cancelMethod();
        }
    }
}

第一个版本没有Object.setPrototypeOf(..),但推荐on the TypeScript GitHub page

当我尝试使用它时,我收到运行时错误(没有编译错误):

class Test{

    async postFileAjax<T>(file: File): CancelablePromise <T> { 

        var promiseFunc = (resolve) => { resolve() };
        var promise = new CancelablePromise<T>(promiseFunc);
        promise.cancelMethod = () => { console.log("cancel!") };

        return promise;
    }
}

var test = new Test();
test.postFileAjax(null);

错误:

(unknown) Uncaught TypeError: undefined is not a promise
    at CancelablePromise.Promise (<anonymous>)
    at new CancelablePromise (<anonymous>:44:28)
    at __awaiter (<anonymous>:7:12)
    at Test.postFileAjax (<anonymous>:62:16)
    at <anonymous>:75:6
    at HTMLButtonElement.excuteButton.onclick (https://www.typescriptlang.org/play/playground.js:242)

我做错了什么?我在ES6中看到你可以继承Promise(参见stackoverflow question),所以我也希望它也能用在TypeScript中。

使用Typescript 2.1并定位es5

如果您在TypeScript Playground中运行代码,点击&#34;运行&#34;您可以看到相同的结果并在新页面中检查控制台( F12 )。

Error in console

如何解决此运行时错误?

PS:stackoverflow上的相关错误是here,但是编译错误并解决了。我已经拆分了编译和运行时错误。

1 个答案:

答案 0 :(得分:2)

我简化了你的例子;这样运行没有错误:

interface CancelablePromise<T> extends Promise<T> {
    cancel: () => void;
}

class Test {
    postFileAjax<T>(file: File): CancelablePromise<T> {
        const promiseFunc = (resolve) => { resolve() };
        const promise = new Promise<T>(promiseFunc);
        const cancel = () => { console.log("cancel!") };
        const cancelablePromise = Object.assign(promise, { cancel });
        return cancelablePromise;
    }
}

const test = new Test();
const testPromise = test.postFileAjax(null);
testPromise.cancel();

TypeScript Playground

  • 我使用了接口继承而不是新类。
  • 我将cancel功能权限复制到promise