本文只关注axios源码注销请求知识点的实现。如果想看完整的源码分析,请移步若川老师的axios源码分析。axios是基于promise封装的,要看axios,首先要了解promises。使用constCancelToken=axios.CancelToken;constsource=CancelToken.source();varoptions={url:'xxxx',data:{},method:'post',cancelToken:source.token};axios(options).then(function(res){})//调用cancel取消请求source.cancel('requestcanceled');如上:调用source.cancel取消请求问题:source.cancel为什么可以取消请求?取消请求的源码实现先看axios\lib\adapters\xhr.js中什么时候取消请求。源码如下:if(config.cancelToken){//处理取消请求config.cancelToken.promise.then(functiononCanceled(cancel){if(!request){return;}//取消请求request.abort();reject(cancel);//清理请求request=null;});可以在config.cancelToken.promise中看到。then中cancel的问题:config.cancelToken.promise.then是什么时候调整的?为什么source.cancel可以触发then的执行呢?取消请求实现在查看源代码之前。先看一个小例子:lett=newPromise((resolve)=>{resolve('execute')})t.then(res=>{console.log(res)})这里只执行t.then,'Execute'被打印出来。如果我想在任何地方执行resolve('execute'),我只能通过setTimeout执行t.then,但是axios源码中config.cancelToken.promise.then的调用时间已经死了,我们只能控制config.cancelToken.promise.then的执行通过source.cancel改造上面的代码:lett=newPromise((resolve)=>{//保存resolve引用,需要执行ThenexecutedelayedResolve=resolve})t.then(res=>{console.log(res)})setTimeout(()=>{delayedResolve('需要执行的时候执行')},3000)可以看到,我们可以灵活控制delayedResolve的调用时间触发t.then的执行。axios取消请求源码:functionCancelToken(executor){if(typeofexecutor!=='function'){thrownewTypeError('executormustbeafunction.');}varresolvePromise;this.promise=newPromise(functionpromiseExecutor(resolve){resolvePromise=resolve;});var令牌=这个;executor(functioncancel(message){if(token.reason){//已经请求取消返回;}token.reason=newCancel(消息);resolvePromise(token.reason);});}CancelToken.source=functionsource(){varcancel;vartoken=newCancelToken(functionexecutor(c){cancel=c;});return{token:token,//返回一个构造函数cancel:cancel};};分析:cancel一定是一个函数,CancelToken接收一个函数执行器,执行器接收另一个函数cancel=functioncancel(message),将这个函数复制到CancelToken.source.cancel,cancel调用CancelToken.promise的resolve,所以你可以随时调用source.cancel来触发CancelToken.promise的resolve
