Open jiefancis opened 3 years ago
axios是对XMLHttpRequest的封装,XMLHttpRequest是通过abort实现请求取消。XMLHttpRequest.onabort被中止后执行的函数。
lib/adapters/xhr是对xmlhttprequest的请求封装,其中取消请求的代码是if(config.cancelToken),这个cancelToken属性是我们在axios(config)中传入的cancelToken属性。
lib/cancel/cancelToken主要实现创建promise实例,并赋值给cancelToken的实例并将cancelToken.promise实例的resolve操作外放到cancelToken.cancel函数中,当在ajax请求中执行source.cancel()操作时,将会触发config.cancelToken.promise的resolve操作进而执行lib/adapters/xhr文件中的config.cancelToken.promise.then(res => request.abort)操作实现取消请求。
// 拼接ajax get url function buildUrl(baseURL, url, params){ if(params) { params = Object.entries(params).map(([key,value]) => `${key}=${value}`).join('&') return `${url}?${params}` } return baseURL ? baseURL + url : url } // 发起ajax请求 function xhr(config){ return new Promise((resolve, reject) => { const request = new XMLHttpRequest() const requestData = config.data const requestParams = config.params let { method, baseURL, url } = config url = buildUrl(baseURL,url, requestParams) if(config.cancelToken) { config.cancelToken.promise.then(reason => { request.abort() }) } request.open(method.toLowerCase(), url, true) request.onreadystatechange = function() { if(request.readyState === 4) { request.status === 200 ? resolve(request.response) : reject(request) } } request.send(requestData) }) } function CancelToken(excutor){ let resolvePromise = null this.promise = new Promise((resolve, reject) => { resolvePromise = resolve }) // cancelToken.promise的resolve操作外放至source.cancel函数中 excutor(function(){ resolvePromise() }) } CancelToken.source = function(){ let cancel = undefined; let token = new CancelToken(function excutor(c){ cancel = c }) return { cancel, token } } const source = CancelToken.source() xhr({ method: 'get', url: 'https://plugins.kancloud.cn/api/plugin/info', cancelToken: source.token, params: { book: 26419, name: 'theme-default,highlight' } }).then(res => { console.log('res', res) }).catch(err => { console.log('err', err) }) setTimeout(() => { source.cancel() },50)
关于axios取消request请求的原理
axios取消xmlhttprequest的设计
lib/adapters/xhr是对xmlhttprequest的请求封装,其中取消请求的代码是if(config.cancelToken),这个cancelToken属性是我们在axios(config)中传入的cancelToken属性。
lib/cancel/cancelToken主要实现创建promise实例,并赋值给cancelToken的实例并将cancelToken.promise实例的resolve操作外放到cancelToken.cancel函数中,当在ajax请求中执行source.cancel()操作时,将会触发config.cancelToken.promise的resolve操作进而执行lib/adapters/xhr文件中的config.cancelToken.promise.then(res => request.abort)操作实现取消请求。
对axios的abort简化版实现