【发布时间】:2021-03-17 12:36:15
【问题描述】:
以下实现抛出错误(见下方评论),如何解决?
interface PromiseWithAbort extends Promise<unknown> {
abort: () => void
}
export const pause = (
ms?: number,
cb?: (...args: unknown[]) => unknown,
...args: unknown[]
): PromiseWithAbort => {
let timeout
// Error: Property 'abort' is missing in type 'Promise<unknown>'
// but required in type 'PromiseWithAbort'.
const promise: PromiseWithAbort = new Promise((resolve, reject) => {
timeout = setTimeout(async () => {
try {
resolve(await cb?.(...args))
} catch (error) {
reject(error)
}
}, ms)
})
promise.abort = () => clearTimeout(timeout)
return promise
}
【问题讨论】:
-
请注意,这种可取消承诺的简单方法无法扩展;一旦你在承诺上使用
then或catch,你就会失去这个方法。这是一个棘手的问题,但您可以考虑将可选的AbortSignal传递给pause。 -
@T.J.Crowder 你能否详细说明“一旦你使用 then 或抓住承诺,你就失去了方法”?我真的不明白。
-
then、catch等创建新的 Promise,通常与您调用它们的 Promise 类型相同。上面的 promise 是标准的Promise,所以来自then/catch/finally的新 promise 不会有abort方法。 -
再一次,我只是说它无法扩展。 Promise 的强大之处在于它们的标准语义以及将它们组合在一起的方式。当您像上面那样自定义实例时,您会破坏这两件事。那里的代码假定只有初始承诺的接收者有理由中止事情,但即使只是
async function example() { return pause(); } example().abort();也会中断。无论如何,编码愉快! -
:-) 我已经更新了答案。编码快乐!
标签: javascript typescript types type-definition