日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(Ajax)axios源码简析(三)——请求与取消请求

發布時間:2025/3/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (Ajax)axios源码简析(三)——请求与取消请求 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門:

  • axios源碼簡析(一)——axios入口文件
  • axios源碼簡析(二)——Axios類與攔截器
  • axios源碼簡析(三)——請求與取消請求

請求過程

在Axios.prototype.request中我們看到,要先通過請求攔截器,才能進行請求。下面看一下dispatchRequest()是如何實現的

// /lib/core/dispatchRequest.jsmodule.exports = function dispatchRequest(config) {// 判斷是否已經取消請求throwIfCancellationRequested(config);/* 對請求的url、headers、data進行處理 */// 發動請求的函數,返回一個promisevar adapter = config.adapter || defaults.adapter;return adapter(config).then(function onAdapterResolution(response) {// 判斷是否已經取消請求throwIfCancellationRequested(config);// 處理返回的數據response.data = transformData(response.data,response.headers,config.transformResponse);return response;}, function onAdapterRejection(reason) {if (!isCancel(reason)) {// 判斷是否已經取消請求throwIfCancellationRequested(config);// 處理返回的錯誤信息if (reason && reason.response) {reason.response.data = transformData(reason.response.data,reason.response.headers,config.transformResponse);}}return Promise.reject(reason);});

如果用戶有在配置中傳入adapter,將使用defaults.adapter,根據運行環境是瀏覽器還是nodejs采取不同的請求方式。

// /lib/defaults.js function getDefaultAdapter() {var adapter;if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {// nodejs環境adapter = require('./adapters/http');} else if (typeof XMLHttpRequest !== 'undefined') {// 瀏覽器環境adapter = require('./adapters/xhr');}return adapter; }var defaults = {adapter: getDefaultAdapter(),/* 其他配置 */ };modules.exports = defaults;

/lib/adapters/http.js與/lib/adapters/xhr.js兩個文件導出的函數都返回一個promise,具體的實現方式就不分析了。里面有很多http請求的細節,可以仔細研究。

取消請求

官方文檔中的調用方法

const CancelToken = axios.CancelToken; const source = CancelToken.source();axios.get('/user/12345', {cancelToken: source.token }).catch(function(thrown) {if (axios.isCancel(thrown)) {console.log('Request canceled', thrown.message);} else {// handle error} });axios.post('/user/12345', {name: 'new name' }, {cancelToken: source.token })// cancel the request (the message parameter is optional) source.cancel('Operation canceled by the user.');

我們進入CancelToken類,找到了CancelToken.source()方法:

// /lib/cancel/CancelTokenCancelToken.source = function source() {var cancel;var token = new CancelToken(function executor(c) {cancel = c;});return {token: token,cancel: cancel}; };

可以看出,CancelToken.source().token是一個CancelToken類的實例,CancelToken.source().cancel是new CacelToken()時傳入參數(一個函數)的參數(也是個函數),通過CancelToken的構造函數可以看出:

// /lib/cancel/CancelTokenfunction 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 requestedreturn;}token.reason = new Cancel(message);resolvePromise(token.reason);}); }

CancelToken.source().cancel就是這個函數:

function cancel(message) {if (token.reason) {// Cancellation has already been requestedreturn;}token.reason = new Cancel(message);resolvePromise(token.reason); }

CancelToken.source().token有promise和reason兩個屬性,promise 一直處于 pending狀態,reason屬性是一個Cancel類的實例,Cancel類的構造函數如下:

// /lib/cancel/Cancel.js function Cancel(message) {this.message = message; }Cancel.prototype.toString = function toString() {return 'Cancel' + (this.message ? ': ' + this.message : ''); };Cancel.prototype.__CANCEL__ = true;

在源碼中,有以下幾種方式檢測是否執行了取消請求。
1 檢測config.cancelToken是否有reason屬性,如果有,將reason拋出,axios進入rejected狀態。

// /lib/core/dispatchRequest.js function throwIfCancellationRequested(config) {if (config.cancelToken) {config.cancelToken.throwIfRequested();} }module.exports = function dispatchRequest(config) {// 判斷是否已經取消請求throwIfCancellationRequested(config);/* ... */ };// /lib/cancel/CancelToken CancelToken.prototype.throwIfRequested = function throwIfRequested() {if (this.reason) {throw this.reason;} };

2 在請求過程中,執行CancelToken.source().token的promise屬性中的resolve函數,參數是CancelToken.source().token.reason,并將其拋出,promise進入rejected狀態

if (config.cancelToken) {// Handle cancellationconfig.cancelToken.promise.then(function onCanceled(cancel) {if (!request) {return;}// 取消請求request.abort();// promise進入rejectedreject(cancel);// Clean up requestrequest = null;}); }

調用方法中catch接到的thrown,就是CancelToken.source().token.reason。

如果在使用axios時候,只在config中添加{cancelToken: source.token},而不調用source.cancel(),則CancelToken.source().token不會有reason屬性,CancelToken.source().token.promise也一直是pending狀態。請求不會取消。

參考

深入淺出 axios 源碼
axios源碼分析——取消請求

總結

以上是生活随笔為你收集整理的(Ajax)axios源码简析(三)——请求与取消请求的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。