可以在 Typescript 中为 Promise 添加取消方法吗?

bro*_*son 7 typescript

我想创建一个 QueryPromise,它只是一个带有取消方法的具体承诺。以下是它的使用方法:

function runQuery(text: string): QueryPromise {
  return new QueryPromise((resolve,reject) => {nativeQuery(resolve)})
}
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试,希望很容易理解:

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

// create the promise my app will use
type QueryPromise = CancellablePromise<string|boolean>
Run Code Online (Sandbox Code Playgroud)

但这还不够。

经过几个小时的反复试验,我设法接近了,但这似乎很乏味,而且很干。

interface CancellablePromise<T> extends Promise<T> {
  cancel: () => void
}
// also need this interface so the variable can be declared
// plus need to redeclare methods to return the new type
interface CancellablePromiseConstructor extends PromiseConstructor {
  new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): CancellablePromise<T>;
  cancel: () => void
}

type QueryPromise = CancellablePromise<string|boolean>    // for parameter types
var QueryPromise: CancellablePromiseConstructor = Promise // for the new operator

// some example code to exercise the promise
function runQuery(text: string): QueryPromise {
  return new QueryPromise((resolve,reject) => {nativeQuery(resolve)})
}
Run Code Online (Sandbox Code Playgroud)

我觉得我在错误的道路上走了很长一段路......有没有人知道更好的方法来做到这一点?

Pal*_*leo 6

TypeScript接口类型描述合约。你的很好:

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

type QueryPromise = CancellablePromise<string | boolean>
Run Code Online (Sandbox Code Playgroud)

然后您可以根据需要实施合同。这是一个例子:

function runQuery(text: string): QueryPromise {
  let rejectCb: (err: Error) => void
  let p: Partial<QueryPromise> = new Promise<string | boolean>((resolve, reject) => {
    rejectCb = reject
    /* ... Here the implementation of the query ... */
  });
  p.cancel = () => {
    /* ... Here the implementation of the aborting ... */
    rejectCb(new Error("Canceled"))
  }
  return p as QueryPromise
}
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 履行cancel应拒绝的承诺;
  • Partial<QueryPromise>用来以后添加成员cancel