极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。
山月训练营之面试直通车 服务上线了,从准备简历、八股文准备、项目经历准备、面试、面经、面经解答、主观问题答复、谈薪再到入职的一条龙服务。

# 如何取消请求的发送

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 502 (opens new window)

Author

回答者: evle (opens new window)

根据发送网络请求的 API 不同,取消方法不同

  • xhr
  • fetch
  • axios

如果使用XMLHttpRequest发送请求可以使用XMLHttpRequest.abort()

如果使用fetch发送请求可以使用AbortController

const controller = new AbortController();
const signal = controller.signal;
fetch('https://somewhere', { signal })
controller.abort()

如果使用axios,取消原理同 fetch

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

axios.get('/https://somewhere', {
  cancelToken: source.token
}

source.cancel()

# 001 XHR 使用 xhr.abort()

const xhr = new XMLHttpRequest(),
  method = "GET",
  url = "https://developer.mozilla.org/";
xhr.open(method, url, true);

xhr.send();

// 取消发送请求
xhr.abort();

# 002 fetch 使用 AbortController

AbortController 文档见 AbortSignal - MDN (opens new window),它不仅可以取消 Fetch 请求发送,同样也可以取消事件的监听(通过 addEventListener 的第三个参数 signal 控制)

  1. 发送请求时使用一个 signal 选项控制 fetch 请求
  2. control.abort() 用以取消请求发送
  3. 取消请求发送之后会得到异常 AbortError
const controller = new AbortController()
const signal = controller.signal

const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

// 点击取消按钮时,取消请求的发送
abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
   // 请求被取消之后将会得到一个 AbortError
    reports.textContent = 'Download error: ' + e.message;
  })
}

# 003 Axios: xhrhttp/https

Axios 中通过 cancelToken 取消请求发送

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.");

而其中的原理可分为两部分

@evle 可以使用 js 代码高亮一下,其实 CancelToken 的底部原理是基于 xhr 的

Last Updated: 11/27/2021, 6:11:48 PM