axios取消请求原理

1,451 阅读1分钟
  • 用法
const CancelToken = axios.CancelToken; 
let cancel;  
axios.get('/user/12345', {   
    cancelToken: new CancelToken(function executor(c) {     
        // executor 函数接收一个 cancel 函数作为参数     
        cancel = c;   
    }) 
 });  // cancel the request cancel();

  • 伪代码实现
function Cancel(message) {
  this.message = message;
}

function CancelToken(executor) {
  if (typeof executor !== 'function') {
    throw new TypeError('executor must be a function.');
  }

  var resolvePromise;
  this.promise = new Promise(function promiseExecutor(resolve) {
    resolvePromise = resolve;
  });

  var token = this;
  executor(function cancel(message) {
    if (token.reason) {
      // Cancellation has already been requested
      return;
    }

    token.reason = new Cancel(message);
    resolvePromise(token.reason);
  });
}


function axios(config) {
  return new Promise((resolve, reject)=>{
    var xhr = new XMLHttpRequest(),
        method = "GET",
        url = "/";

    if(config.cancelToken) {
      config.cancelToken.promise.then((cancel)=> {
        xhr.abort();
        reject(cancel);
      });
    }
    xhr.open(method, url, true);
    xhr.send();
    
  })
}


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

cancel()

调用 cancel 让 CancelToken实例属性promise resolve 从而调用

config.cancelToken.promise.then((cancel)=> {
    xhr.abort();
    reject(cancel);
});

取消ajax
rejected 抛出错误