0

我正在使用 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;
  }
}),

所以我不确定取消这些请求的最佳方法是什么。

4

2 回答 2

0

您可以使用axios 提供的取消令牌在新请求开始时取消挂起的请求(然后每次我想都必须创建一个新令牌)。

但是我记得那个方法有一些问题(它冻结了我的整个应用程序),我最终使用了 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;

于 2019-06-12T07:51:58.800 回答
0

我在这里遇到同样的问题。其实不完全。只是我的架构容易受到同样类型的问题的影响(现在我正在考虑它)。我想我们应该做的是存储路由器的状态(可能处于volatile 状态)并在尝试请求任何路由之前咨询它。然后,如果有必要,我们可以停止更改路由,或者取消先前的请求(并且请求应该通过可取消的实用程序发出),然后再创建一个新请求。

潜在地,您还可以添加一个能够在任何阶段取消异步操作的中间件。因此,您可能会在操作的每个阶段咨询上述标志,并在检测到冲突时退出。但这不会阻止请求本身。

第三种选择,也是我猜的最好的选择,是为每个请求创建一个不稳定的状态,带有一个状态和对实际请求的引用,以便它可以在销毁时自动取消它。一旦您将新请求分配给树上的同一节点,就会触发销毁。

于 2019-06-12T07:16:38.997 回答