在执行“即时搜索”类型的输入框时取消axios请求

时间:2019-02-28 09:17:10

标签: reactjs axios

我有:

  function testURL(url) {
    return axios.post(`http://localhost:4000/api/test`, { url } )
  }

  onChangeDestination(url, index) {
    this.setState(prevState => {
      const rules = [...prevState.rules];
      const url_status = "Checking"
      rules[index] = { ...rules[index], url, url_status};
      return { rules };
    });
    if (isURL(url+'')) {
        testURL(url).then(r=> {
          var url_status = r.data.response
          this.setState(prevState => {
            const rules = [...prevState.rules];
            rules[index] = { ...rules[index], url_status};
            return { rules };
          });
        })
      } else {
        this.setState(prevState => {
          const rules = [...prevState.rules];
          var url_status = "No URL"
          rules[index] = { ...rules[index], url_status};
          return {rules};
        });
      }
  };

因此,我有一个用于onChangeDestination(即击键)的URL的文本输入,它进行回调并检查URL的解析度(url_status)。它类似于Google即时搜索的工作方式。我遇到的问题是,有时对axios的响应可能会混乱,这意味着最后的url_status不一定来自最后的击键。

我正在尝试找出如何使用axios的cancel API,但是我正在努力弄清楚如何构造它。什么是取消令牌,我应该在哪里存储它?

4 个答案:

答案 0 :(得分:1)

我想你是要这个。 Axios cancellation

const CancelToken = axios.CancelToken;
let cancel;
function testURL(url) {
    return axios.post(`http://localhost:4000/api/test`, { url,
      cancelToken: new CancelToken(function executor(c) {
       // An executor function receives a cancel function as a parameter
      cancel = c;
      }
   })
 }


...
// whenever you need to cancel request
// by calling cancel();


onChangeDestination(url, index) {
if(rules[index].url !== url) { // i have added this check 
   cancel();
 // implement  call again() 
}else{
  // usual call 
}
};
...

答案 1 :(得分:0)

您可以使用取消令牌取消请求。

您可以使用CancelToken.source工厂创建一个取消令牌,如下所示:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

您还可以通过将执行程序函数传递给CancelToken构造函数来创建取消令牌:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();
  

注意:您可以使用相同的取消令牌取消多个请求。

答案 2 :(得分:0)

应该可以解决问题。 它只是检查呼叫是否正在执行(挂起状态),如果是,导航器将取消呼叫。

_source = undefined

testURL = url => {
     if (this._source) this._source.cancel()
     this._source = axios.CancelToken.source()

     return axios.post(`http://localhost:4000/api/test`, 
          { url }, 
          { cancelToken: this._source.token })
  }

答案 3 :(得分:0)

除了现有的显示如何取消已发出呼叫的建议(您仍然应该这样做)之外,还有一个额外建议。如果您还debounce进行输入怎么办,那么首先要取消的呼叫就更少了?

请参阅http://demo.nimius.net/debounce_throttle/了解反跳的作用。