# 网络请求的取消

# XMLHttpRequest

<button id="btnSend">发送请求</button>
<button id="btnCancel">取消请求</button>
var xhr; 
function sendRequest(){
    xhr = new XMLHttpRequest(); // 新建一个xhr对象
    xhr.withCredentials = true;
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            console.log(xhr.responseText);
        }
    };
    xhr.open("post", "http://127.0.0.1:3000/xhr", true);
    xhr.send();
}

btnSend.onclick = function () {
    sendRequest();
};

btnCancel.onclick = function(){
    xhr && xhr.abort();
}

# fetch

const controller = new AbortController();
const signal = controller.signal;

function sendFetch(test) {
  fetch("http://127.0.0.1:3000/fetch", { signal })
    .then((response) => {
      return response.text();
    })
    .then((text) => {
      console.log(text);
    });
}

btnSend.onclick = function () {
  sendFetch();
};

btnCancel.onclick = function () {
  console.log("取消请求");
  controller.abort();
};

# axios网络请求的取消

# AbortController方式

const controller  = new AbortController();

axios.get('/foo/bar',{signal:controller.signal}).then(()=>{
  // ...
})

controller.abort()

# cancelToken方式

// -------------------方式1-------------------
const cancelToken  = axios.cancelToken
const source = cancelToken.source();

axios.get('/foo/bar',{
  cancelToken:source.token
}).catch(error=>{
  if(axios.isCancel(error)){
    // 请求已取消
  }else{
    // 其他错误
  }
})

// 取消操作
source.cancel('请求被用户取消')

// -------------------方式2-------------------
const cancelToken  = axios.cancelToken
let cancel;

axios.get('/foo/bar',{
  cancelToken:new cancelToken(function(c){
    cancel = c
  })
})

// 执行该cancel即可
cancel()

# 请求到达服务器后服务器未作响应

提示

代码示例同上 fetch

# 请求到达服务器前取消

 const controller = new AbortController();
const signal = controller.signal;

function sendFetch(ticket, options = {}) {
  fetch(`http://127.0.0.1:3000/fetch?ticket=${ticket}`, options)
    .then((response) => {
      return response.text();
    })
    .then((text) => {
      console.log(text);
    });
}

btnSend.onclick = function () {
  // chrome 默认是6个连接
  sendFetch(1);
  sendFetch(2);
  sendFetch(3);
  sendFetch(4);
  sendFetch(5);
  sendFetch(6);

  sendFetch(7);
  sendFetch(8);
  sendFetch(9, { signal });
};

btnCancel.onclick = function () {
  console.log("取消请求");
  controller.abort();
};

# 请求失败重试

/**
 * 发出请求,返回promise
 * @param {string} url 请求地址
 * @param {number} maxCount 最大重试次数
 */

const request = (url, maxCount = 5) => {
  return fetch(url).catch(err=>{
    maxCount <=0 ? Promise.reject(err) : request(url,maxCount-1)
  })
}
Last Updated: 1/15/2023, 10:19:00 PM