为什么 axios 既可以用 axios({})这样请求 ,也可以 axios.get()这样请求? 在使axios.create
的时候,调用了这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 /** * Create an instance of Axios * * @param {Object} defaultConfig The default config for the instance * @return {Axios} A new instance of Axios */ function createInstance(defaultConfig) { var context = new Axios(defaultConfig);//生成配置 和拦截器 var instance = bind (Axios.prototype.request, context); utils.extend(instance, Axios.prototype, context); utils.extend(instance, context); return instance; }
从图中可以看到,方法之类的确实挂载到了原型链上
cancalToken 怎么取消请求的 那么其实什么时候需要取消请求,举一个很常见的例子,取消重复请求,就是当前已经发出请求的情况下,后续同样的请求如果发送就会被取消(如果是表单的提交也可以使用 dom 的 disabld 禁止点击 2333) 举个栗子: 在 axios 上是挂载了 Cancel 相应的东西
axios.Cancel = require(‘./cancel/Cancel’);
axios.CancelToken = require(‘./cancel/CancelToken’);
axios.isCancel = require(‘./cancel/isCancel’);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var data = document.getElementById("data" ).value; const CancelToken = axios.CancelToken; axios .post( "/post/server" , { data, }, { cancelToken: new CancelToken((c) => { cancel = c; console.log(c) }), } ) .then(function (res) { output.className = "container"; output.innerHTML = res.data; }) .catch(function (err) { output.className = "container text-danger"; output.innerHTML = err.message; }); cancel('sdfsd');
然后这里 axios.post 实际上就是调用了request
方法,方法的返回值是一个 promise,最后一个执行的 promise 是一个叫dispatchRequest
的函数,函数位置在 core/dispatchRequest.js 文件下,因为返回的是一个 promise ,状态是 pendding,加入到微任务队列,然后执行主线程的cancel
方法。cancel 方法是在初始化 cancelToken 的时候给 cancel 赋值了。
cancelToken:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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) { return ; } token.reason = new Cancel(message); resolvePromise(token.reason); }); }
主线程任务执行完成的时候开始进入下一轮任务执行,没有宏任务需要执行,直接执行微任务,先执行刚刚 request 返回的 promise,其实是开始执行了dispatchRequest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 module.exports = function dispatchRequest(config) { throwIfCancellationRequested(config); } /** * Throws a `Cancel` if cancellation has been requested. */ function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } } CancelToken.prototype.throwIfRequested = function throwIfRequested () { if (this.reason) { throw this.reason; } };
在xhr文件中看到有一段代码,长这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 if (config.cancelToken) { // Handle cancellation config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return ; } request.abort(); reject(cancel); // Clean up request request = null; }); }
那么上文中的resolvePromise改变后的promise就是在这里调用,那什么情况会到这里来执行请求,假如有A,B两个请求,A请求响应时间过长,然后等到B执行回调都回来的时候,直接把A请求给取(gan)消(diao)了