jtwang7 / JavaScript-Note

JavaScript学习笔记
10 stars 2 forks source link

axios 取消请求 #55

Open jtwang7 opened 2 years ago

jtwang7 commented 2 years ago

axios 取消请求

从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求:

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// 取消请求
controller.abort()
jtwang7 commented 1 year ago

旧版本 axios 取消请求

前言

ajax 请求可以通过 .abort() 方法取消请求,axios 请求则使用了 cancelToken

axios cancelToken 基本使用

axios-cancelToken

CancelToken.source

可以使用 CancelToken.source 工厂方法创建 cancel token:

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 {
     // 处理错误
  }
});

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

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

CancelToken.executor

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// cancel the request
cancel();

注意: 可以使用同一个 cancel token 取消多个请求

可能遇到的问题

Cannot read property ‘cancelToken‘ of undefined“

假如在请求拦截器中配置 cancelToken 时,需要在获取 config 参数之后,最终返回 config。请求拦截器会将 config 拦截后做一些处理,然后需要将拦截的 config 重新传递下去,否则后续就缺少了 config 参数。

请求取消后,同一请求就无法再次发送

这是因为使用了 cancel 后,cancelToken 就会被注册在调用的请求中,导致再一次发送相同请求时,会因为残留的 cancelToken 默认取消了请求。解决方法就是,在每次创建 cancelToken 时,将 cancel 回调保存到一个列表中,在 cancel 回调调用后,将它从列表中移除,cancel 所绑定的 cancelToken 也会被一并移除回收,这样就可以重新发送相同的请求。