如何在axios中取消/中止ajax请求

Raj*_*rov 24 flux reactjs reactjs-flux es6-promise axios

axios用于ajax请求和reactJS+ flux用于渲染UI.在我的应用程序中有第三个时间轴(reactJS组件).时间轴可以通过鼠标滚动来管理.应用程序在任何滚动事件后发送实际数据的ajax请求.服务器上的请求处理可能比下一个滚动事件更慢的问题.在这种情况下,应用程序可以有几个(通常2-3个)已经弃用的请求,因为用户进一步滚动.这是一个问题,因为每次接收新数据时间线都会开始重绘.(因为它是reactJS + flux)因此,用户会多次来回看时间轴的移动.解决此问题的最简单方法是,它只是中止以前的ajax请求jQuery.例如:

    $(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);
Run Code Online (Sandbox Code Playgroud)

如何取消/中止请求axios

Nic*_*sev 27

Axios目前不支持取消请求.有关详细信息,请参阅此问题.

更新:axios v0.15中添加了取消支持.

  • 请注意,运行“axios.post”时,它应该位于第三个参数中!像这样: `axios.post('/user/12345', {}, { cancelToken: cancelTokenSource.token });` (7认同)
  • 从 axios v0.22.0 开始,`CancelToken` 方法已被弃用。他们建议使用 [AbortController](https://github.com/axios/axios#abortcontroller) 方法代替 (5认同)
  • 如果链接的资源出现故障,请包含一个最小的示例! (4认同)
  • `const cancelTokenSource = axios.CancelToken.source(); axios.get('/user/12345', { cancelToken: cancelTokenSource.token }); cancelTokenSource.cancel();` (3认同)
  • 如果你这样做,它就不能再运行了 (2认同)

ano*_*ewb 26

使用 useEffect 钩子:

useEffect(() => {
  const ourRequest = Axios.CancelToken.source() // <-- 1st step

  const fetchPost = async () => {
    try {
      const response = await Axios.get(`endpointURL`, {
        cancelToken: ourRequest.token, // <-- 2nd step
      })
      console.log(response.data)
      setPost(response.data)
      setIsLoading(false)
    } catch (err) {
      console.log('There was a problem or request was cancelled.')
    }
  }
  fetchPost()

  return () => {
    ourRequest.cancel() // <-- 3rd step
  }
}, [])
Run Code Online (Sandbox Code Playgroud)

注意:对于 POST 请求,将 cancelToken 作为第三个参数传递

Axios.post(`endpointURL`, {data}, {
 cancelToken: ourRequest.token, // 2nd step
})
Run Code Online (Sandbox Code Playgroud)


小智 23

import React, { Component } from "react";
import axios from "axios";

const CancelToken = axios.CancelToken;

let cancel;

class Abc extends Component {
  componentDidMount() {
    this.Api();
  }

  Api() {
      // Cancel previous request
    if (cancel !== undefined) {
      cancel();
    }
    axios.post(URL, reqBody, {
        cancelToken: new CancelToken(function executor(c) {
          cancel = c;
        }),
      })
      .then((response) => {
        //responce Body
      })
      .catch((error) => {
        if (axios.isCancel(error)) {
          console.log("post Request canceled");
        }
      });
  }

  render() {
    return <h2>cancel Axios Request</h2>;
  }
}

export default Abc;

Run Code Online (Sandbox Code Playgroud)

  • 您不应该*永远*在组件内使用模块作用域变量。如果渲染其中两个,则每个都将清除前一个设置的值。 (2认同)

Ahm*_*aki 22

通常,您希望取消之前的 ajax 请求并忽略它即将到来的响应,只有当该实例的新 ajax 请求开始时,为此,请执行以下操作:

示例:从 API 获取一些评论:

// declare an ajax request's cancelToken (globally)
let ajaxRequest = null; 

function getComments() {

    // cancel  previous ajax if exists
    if (ajaxRequest ) {
        ajaxRequest.cancel(); 
    }

    // creates a new token for upcomming ajax (overwrite the previous one)
    ajaxRequest = axios.CancelToken.source();  

    return axios.get('/api/get-comments', { cancelToken: ajaxRequest.token }).then((response) => {
        console.log(response.data)
    }).catch(function(err) {
        if (axios.isCancel(err)) {
           console.log('Previous request canceled, new request is send', err.message);
        } else {
               // handle error
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


Kor*_*nel 7

有一个非常好的软件包,其中包含一些称为 axios-cancel 的用法示例。我发现它很有帮助。这是链接:https : //www.npmjs.com/package/axios-cancel


moh*_*ari 6

https://github.com/axios/axios#cancellation

const CancelToken = axios.CancelToken;
                const source = CancelToken.source();
                let url = 'www.url.com'


                axios.get(url, {
                    progress: false,
                    cancelToken: source.token
                })
                    .then(resp => {

                        alert('done')

                    })

                setTimeout(() => {
                    source.cancel('Operation canceled by the user.');
                },'1000')
Run Code Online (Sandbox Code Playgroud)


Leg*_*las 5

这就是我在 node.js 中使用 promise 的方式。发出第一个请求后轮询停止。

 var axios = require('axios');
    var CancelToken = axios.CancelToken;
    var cancel;
    axios.get('www.url.com',
                      {
                        cancelToken: new CancelToken(
                            function executor(c) {
                                cancel = c;
                             })
                      }
            ).then((response) =>{            
                cancel();               
              })
Run Code Online (Sandbox Code Playgroud)


Dmi*_*voy 5

使用cp-axios包装器,您可以使用三种不同类型的取消 API 中止您的请求:

1. Promise取消API(CPromise):

实时浏览器示例

 const cpAxios= require('cp-axios');
 const url= 'https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=5s';
 
 const chain = cpAxios(url)
      .timeout(5000)
      .then(response=> {
          console.log(`Done: ${JSON.stringify(response.data)}`)
      }, err => {
          console.warn(`Request failed: ${err}`)
      });
 
 setTimeout(() => {
    chain.cancel();
 }, 500);
Run Code Online (Sandbox Code Playgroud)

2.使用AbortController信号API:

 const cpAxios= require('cp-axios');
 const CPromise= require('c-promise2');
 const url= 'https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=5s';
 
 const abortController = new CPromise.AbortController();
 const {signal} = abortController;
 
 const chain = cpAxios(url, {signal})
      .timeout(5000)
      .then(response=> {
          console.log(`Done: ${JSON.stringify(response.data)}`)
      }, err => {
          console.warn(`Request failed: ${err}`)
      });
 
 setTimeout(() => {
    abortController.abort();
 }, 500);
Run Code Online (Sandbox Code Playgroud)

3. 使用普通的 axios cancelToken:

 const cpAxios= require('cp-axios');
 const url= 'https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=5s';

 const source = cpAxios.CancelToken.source();
 
 cpAxios(url, {cancelToken: source.token})
      .timeout(5000)
      .then(response=> {
          console.log(`Done: ${JSON.stringify(response.data)}`)
      }, err => {
          console.warn(`Request failed: ${err}`)
      });
 
 setTimeout(() => {
    source.cancel();
 }, 500);
Run Code Online (Sandbox Code Playgroud)

4. 自定义 React hook 中的用法现场演示):

import React from "react";
import { useAsyncEffect } from "use-async-effect2";
import cpAxios from "cp-axios";

/*
 Note: the related network request will be aborted as well
 Check out your network console
 */

function TestComponent({ url, timeout }) {
  const [cancel, done, result, err] = useAsyncEffect(
    function* () {
      return (yield cpAxios(url).timeout(timeout)).data;
    },
    { states: true, deps: [url] }
  );

  return (
    <div>
      {done ? (err ? err.toString() : JSON.stringify(result)) : "loading..."}
      <button onClick={cancel} disabled={done}>
        Cancel async effect (abort request)
      </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

更新

Axios v0.22.0+AbortController原生支持:

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// cancel the request
controller.abort()
Run Code Online (Sandbox Code Playgroud)