我正在使用axios,我注意到有人去了Route A,然后快速单击一个指向Route B的按钮,Route A请求仍然在运行,并且可能会发生奇怪的结果。
我正在做这样的事情
getAllTaxRates: flow(function*() {
try {
const response = yield self.rootStore().axios.get('/get');
applySnapshot(self.taxRates, response.data);
} catch (error) {
throw error;
}
}),
因此,我不确定取消这些请求的最佳方法是什么。
答案 0 :(得分:0)
我在这里遇到同样的问题。其实不完全是。只是我的体系结构容易遇到相同类型的问题(现在我正在考虑它)。我猜我们应该做的是,在尝试请求任何路由之前,存储路由器的状态(可能在volatile state 中为)并进行查询。然后,如有必要,我们可以停止更改路由,或者取消之前的请求(,并且应该通过可取消的实用程序发出请求),然后再进行新的请求。
可能您还可以add a middleware在任何阶段都可以取消异步操作。因此,您有可能在操作的每个阶段都参考上述标志,并在发现冲突时纾困。但这不会停止请求本身。
我猜第三个也是最好的选择,将是为每个请求创建一个稍微不稳定的状态,并带有一个状态和对实际请求的引用,以便它可以在销毁时自动将其取消。将新请求分配给树上的同一节点后,就会触发并销毁。
答案 1 :(得分:0)
您可以使用axios提供的a Cancel Token在新请求的开头取消待处理的请求(然后,我认为每次都必须创建一个新的令牌)。
但是,我记得该方法存在一些问题(它冻结了我的整个应用程序),最终我使用了Node-Fetch和AbortController,它们非常适合我的使用。 (如this answer所示)
编辑: 大致是我的操作方式,请注意,我的请求函数是异步的(使用Context API,但您应该能够使用Mobx做到这一点)
import React from 'react';
import Context from './Context';
import fetch from 'node-fetch';
class Provider extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
controller: new AbortController(),
};
this.queryAll = this.queryAll.bind(this);
this.abortAllRequest = this.abortAllRequest.bind(this);
}
abortAllRequest() {
this.state.controller.abort();
this.setState({
isLoading: false,
controller: new AbortController(),
});
}
async queryAll(eans) {
if (this.state.isLoading) {
await this.abortAllRequest();
}
const signal = this.state.controller.signal;
const result = await fetch(`/SomUrl/`, {
method: 'get',
signal: signal,
});
}
render() {
return (
<Context.Provider value={{
state: this.state,
queryAll: this.queryAll,
abortAllRequest: this.abortAllRequest,
}}>
{this.props.children}
</Context.Provider>
);
}
}
export default Provider;