axios的cancalToken的用法及原理

https://www.jianshu.com/p/8555a2c757ec 这篇文章写的特别好

基本用法:(token插入,cancel执行)

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

原理:source里面的token是一个处于pending状态的promise,cancel是token的promise对象的resolved,即cancel控制token这个promise的resolved状态

【利用promise的then,promise有结果之后才走then,我们可以在外部控制promise的结果(resolved或rejected,这里自然就是resolved)resolved后自然就去执行then,然后then里面去执行absort()所以把promise的resolved的把控权放到外面给cancel,这样cancel就能轻而易举的控制then里面内容的执行了。通俗点讲,token就是埋在xhr请求里的promise灯,cancel是放在外面的resolved灯开关】

正如开头文章所说的:想要实现取消某个请求,我们需要为该请求配置一个 cancelToken ,然后在外部调用一个 cancel 方法。
请求的发送是一个异步过程,最终会执行 xhr.send 方法,xhr 对象提供了 abort 方法,可以把请求取消。因为我们在外部是碰不到 xhr 对象的,所以我们想在执行 cancel 的时候,去执行 xhr.abort 方法。
我们在 xhr 异步请求的过程中,插入一段代码,当我们在外部执行 cancel 函数的时候,会驱动这段代码的执行,然后执行 xhr.abort 方法取消请求。
取消请求必然是个异步的操作,自然想到用 Promise 实现异步,也就是在 cancelToken 中保存一个 pending 状态的 Promise 对象,然后当我们执行 cancel方法的时候,能够访问这个 Promise 对象,把它从 pending 状态变成 resolved 状态,这样我们就可以在 then 函数中去实现取消请求的逻辑

说了这么一堆,看下下面的代码就懂了
// 创建Promise,返回开关token promise和cancel
function source () {
  let cancel;
  const promise = new Promise((resolve) => {
    cancel = resolve;
  }
  return {
    token: promise  // pending状态的promise
    cancel,      // 使上面的promise变成resolve状态
  }
}
// 发请求
function axios_get (config) {
    const xhr = new XMLHttpRequest(),
    method = "GET",
    url = "https://developer.mozilla.org/";
    xhr.open(method, url, true);
    xhr.send();
    if (config.cancelToken) {
      config.cancelToken.then(() => { // 把token promise插进来
          xhr.abort();
      })
    }
}
// 代码执行
const source = source();
axios_get({ cancelToken: source.token });
setTimeout(() => {
  source.cancel(); // 点燃炸弹,触发token promise的then
}, 5000)

ene

ene

posted @ 2021-12-23 12:47  superil  阅读(544)  评论(0编辑  收藏  举报