【发布时间】:2021-02-02 02:09:20
【问题描述】:
我希望能够从我的 Vue 组件中取消已启动的承诺,特别是 Vuex 操作返回的承诺。
我的用例是我的 Vuex 操作轮询端点的状态,如果用户执行某个操作(示例中的关闭函数),我希望能够取消该轮询。
我创建了一个从另一个 stackoverflow 答案提取的自定义 CancellablePromise 类,但它不适用于 Vuex。
可取消的承诺类(来自https://stackoverflow.com/a/60600274/2152511)
export class CancellablePromise<T> extends Promise<T> {
private onCancel: () => void;
constructor(
executor: (
resolve: (value?: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
onCancel: (cancelHandler: () => void) => void
) => void
) {
let onCancel: () => void;
super((rs, rj) =>
executor(rs, rj, (ch: () => void) => {
onCancel = ch;
})
);
this.onCancel = onCancel;
}
public cancel(): void {
if (this.onCancel) {
this.onCancel();
}
}
}
动作
async [SomeAction.foo]({ state, dispatch, commit, rootGetters }) {
const cancellablePromise = new CancellablePromise<any>((resolve, reject, onCancel) => {
const interval = setInterval(async () => {
const status = await dispatch(SomeAction.bar);
if (status === "goodstatus") {
clearInterval(interval);
resolve();
} else if (status === "badstatus") {
clearInterval(interval);
reject();
}
}, 2000);
onCancel(() => {
clearInterval(interval);
reject();
});
});
return cancellablePromise;
}
组件
data: (() => {
promise: undefined as CancellablePromise<any> | undefined
}),
async call() {
this.promise = this.$store
.dispatch(SomeAction.foo)
.then(response => {
// do something
}) as CancellablePromise<any>;
},
close(): void {
if (this.promise) {
this.promise.cancel(); // outputs cancel is not a function
}
}
问题出现在close 函数中,其中this.promise.cancel 不是函数。
这似乎在我看来是因为dispatch 返回的对象确实是一个Promise,而不是CancelablePromise。我的怀疑来自于查看the Vuex source,它再次似乎从操作返回的Promise 创建一个new Promise。我对 Typescript 的类型系统不是很熟悉,但除非我误读了这段代码,否则我认为我的 CancellablePromise 在这里“丢失”了。
我怎样才能在这里完成我想做的事情?
【问题讨论】:
-
我猜你可以将它添加到原型中:
Promise.prototype.cancel = ...? -
正如您所指出的,Vuex 用新的(不可取消的)
Promise包装了您的CancellablePromise,因此您无法直接从您的操作中访问您自己的承诺。除非您自己修补 Vuex,否则我认为没有办法取消承诺。 -
除了调用
cancel()方法之外,您是否建议使用this.promise? -
@Roamer-1888 不,我不这么认为。为什么?
标签: javascript typescript vue.js promise vuex