本文只关注axios源码之勾销申请这个知识点的实现,如想看残缺源码解析,请移步若川大佬的axios源码解析, axios是基于promise封装的,看axios需先对promise有所理解

  1. 勾销申请的应用

     const CancelToken = axios.CancelToken; const source = CancelToken.source(); var options = {       url: 'xxxx',       data: {},       method: 'post',       cancelToken: source.token }; axios(options).then(function (res) {}) // 调用cancel勾销申请 source.cancel('申请勾销了');

    如上:调用source.cancel便可勾销申请
    疑难:为什么source.cancel能够勾销申请?

  2. 源码对于勾销申请的实现

    1. 先看 axios\lib\adapters\xhr.js 外面是什么时候勾销申请的,源码如下:

      if (config.cancelToken) {      // Handle cancellation      config.cancelToken.promise.then(function onCanceled(cancel) {        if (!request) {          return;        }        // 勾销申请        request.abort();        reject(cancel);        // Clean up request        request = null;      });    }

      可看出在config.cancelToken.promise.then外面勾销的
      疑难:config.cancelToken.promise.then什么时候调的,为什么source.cancel能够触发then的执行?

      1. 勾销申请实现
        看源码之前。先看一个小例子:

        let t = new Promise((resolve) => {    resolve('执行')   })   t.then(res => {     console.log(res)   })

        这里只有执行t.then, '执行'就被打印了,如果我想想在任何须要的中央去执行resolve('执行'),只能同过setTimeout去执行t.then, 然而在axios源码外面config.cancelToken.promise.then的调用工夫曾经定死了,咱们只能通过source.cancel去管制config.cancelToken.promise.then的执行

        革新上方代码:

         let t = new Promise((resolve) => {    // 把resolve援用存起来,须要执行的时候再执行    delayedResolve = resolve  })   t.then(res => {     console.log(res)   })  setTimeout(() => {    delayedResolve('须要执行的时候在执行')  }, 3000)

        能够看到,咱们能够灵便管制delayedResolve的调用工夫来触发t.then的执行
        上axios勾销申请的源码:

        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);  });}
        CancelToken.source = function source() {  var cancel;  var token = new CancelToken(function executor(c) {    cancel = c;  });  return {    token: token, // 返回的一个构造函数    cancel: cancel  };};

        剖析:
        cancel必定是一个函数,CancelToken接管一个函数executor, executor再接管一个函数 cancel = function cancel(message),并将此函数复制给CancelToken.source.cancel,cancel 外面调用了CancelToken.promise的resolve。 由此能够通过任意工夫调用source.cancel来触发CancelToken.promise的resolve