2017-04-14 69 views
0

我试图在Typescript中取消我的async方法调用。Typescript:Promise的子类/扩展在运行时给出'TypeError:undefined不是承诺'

要做到这一点,我创建了一个新的承诺类型,从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中使用。

使用打字稿2.1和定位ES5

你可以看到同样的结果,如果你在TypeScript Playground运行代码,请单击“运行”,在新页面检查控制台(F12)。

Error in console

如何解决这个运行时错误?


PS:在计算器相关的错误here,但编译错误和解决。我已经拆分了编译和运行时错误。

+0

Object.setPrototypeOf(this,CancelablePromise.prototype)是什么原因;'? – unional

+0

@unional它来自链接(也包括在文章中)“建议 - 作为建议,您可以在任何超级(...)调用后立即手动调整原型。” – Julian

回答

1

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

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