(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().cancelnew 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().tokenpromisereason兩個屬性,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().tokenpromise屬性中的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源碼分析——取消請求

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537969.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537969.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537969.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows配置tomcat環境

1、安裝JDK 參考教程: https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.htmlCLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarCLASSPATH這個環境變量一定要配好,否則tomcat起不來,直接復制上面的內容,…

java 抽獎 高并發處理_如何設計高并發下的抽獎?

關于抽獎,需要考慮的點有很多,這里稍微整理了下主要需要考慮以下三點:用戶抽獎次數限制獎品數量限制獎品發放的分布中獎的概率的可控性用戶抽象次數限制一個用戶必須限制抽獎的次數,而同一個用戶的并發幾率其實是很小的,所以這里可以用悲觀鎖來控制用戶的抽獎次數。獎品數量限制…

WPF圓角按鈕與觸發顏色變化

原文:WPF圓角按鈕與觸發顏色變化<Button x:Name"button1" Content"按鈕1" Margin"10,10,0,0" Cursor"Pen"><Button.Template><ControlTemplate><Border CornerRadius"15,15,15,15"><Border.Back…

咖啡豆的勵志故事

好多年前就聽過這個故事&#xff0c;以前沒感觸&#xff0c;最近特有感觸。

java bean spring_JavaBean和Spring bean傻傻分不清楚

JavaBean的定義可序列化提供無參構造提供getter/setter方法疑問在學習 Spring 的過程中發現很多 bean 對象并沒有實現 Serializable 接口或提供其他可序列化的操作。這種也叫 bean&#xff1f;或者 bean 也可以不提供序列化操作&#xff1f;解決stackoverflow 一番后&#xff0…

WPF Image Source 設置相對路徑圖片

原文:WPF Image Source 設置相對路徑圖片BitmapImage bt new BitmapImage(new Uri("Images\\3_u10484.png", UriKind.Relative));this.Img1.Source bt;

PowerDesigner V16.5 安裝教程以及漢化(數據庫建模)

原文地址&#xff1a;https://blog.csdn.net/tgbyn/article/details/72809116 ----------------------------------------------------------------------一、power designer是什么以及是干什么的&#xff1f; power designer是能進行數據庫設計的強大的軟件&#xff0c;是一款…

python調用jar字典類型_LWPCookieJar的使用-將requests存儲的cookie轉換成字典

LWPCookieJar是python中管理cookie的工具&#xff0c;可以將cookie保存到文件&#xff0c;或者在文件中讀取cookie數據到程序寫入cookie到文件from cookielib import LWPCookieJarcj LWPCookieJar()cj.set_cookie(cookielib.Cookie(version0,names_cookie[name],values_cookie…

常用的數字正則匹配

1. 數字 ^[0-9]*$2. 1-60之間的整數 /^([1-5][0-9]$)|(^[6][0]$)|(^[1-9])$/ 3. 0-60的數字&#xff0c;可以精確到小數點后2位 /^(([0-5][0-9])|[0-9]|60|(([0-9]\.\d{1,2}|[1-5][0-9]\.\d{1,2})))$/ 4. 0-1000000的整數  /^(?!00)(?:[0-9]{1,7}|1000000)$/5. 5-10000…

nginx 代理多個服務器——多個server方式

原文鏈接&#xff1a;https://blog.csdn.net/wild46cat/article/details/52997005 ------------------------------------------------------------- 配置文件下載地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400nginx 代理多個服務器——多個server方…

sc openscmanager 失敗 5 mysql_如何增加windows服務

我以前也出現過你這個問題&#xff0c;用優化大師給刪了吧&#xff0c;后來也是重裝的&#xff0c;其實說是重裝也不是重裝&#xff0c;就是修復啦&#xff0c;如果你不想這樣&#xff0c;那可以試試這個&#xff0c;我沒試過用在mysql上&#xff0c;但別的到是用他加載過。讓程…

TemplatePart用法說明

原文:TemplatePart用法說明TemplatePart(Name"PART_Decrease", Typetypeof(RepeatButton)) 一直沒明白這是干嘛用的&#xff0c;搜了一下&#xff0c;記載一下。 以Button的定義為例&#xff1a; namespace System.Windows.Controls {// Summary:// Represents a…

nginx配置多個站點共用80端口

原文鏈接&#xff1a;https://blog.csdn.net/zhezhebie/article/details/73459874 --------------------------------------------- 配置文件下載地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400共用80端口的&#xff0c;要server_name不同。如果用域…

兩點間最短路 java_AcWing 850. Dijkstra求最短路 II_Java實現含詳細注釋

import java.io.*;import java.util.Arrays;import java.util.Comparator;import java.util.PriorityQueue;public class Main {static final int N 150010;static int n, m; //結點數&#xff0c;邊數static int[] h, e, ne, w; //鄰接表適合表示稀疏圖,w用來存每個邊權重sta…

SQL Server如何鏈接到 Oracle并查詢其中的數據?并實現做接口

今天用Oracle的驅動教大家如何從SQL Server鏈接到Oracle. 1. 服務器上需要安裝Oracle 64位的客戶端或者服務端&#xff0c;安裝過程就省略了。不會的同學可以網上搜索一下安裝方法&#xff0c;很詳細&#xff0c;這里不贅述。 安裝完成后SQL Server的訪問接口上會新增”OraOLE…

Tomcat 內存調大

第一種方法&#xff1a;Windows下&#xff0c;在文件/bin/catalina.bat&#xff0c;Unix下&#xff0c;在文件/bin/catalina.sh的前面&#xff0c;增加如下設置&#xff1a;JAVA_OPTS-Xms【初始化內存大小】 -Xmx【可以使用的最大內存】需要把這個兩個參數值調大。例如&#xf…

java spring bean配置文件_Spring基于xml文件配置Bean過程詳解

這篇文章主要介紹了spring基于xml文件配置Bean過程詳解,文中通過示例代碼介紹的非常詳細&#xff0c;對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下通過全類名來配置&#xff1a;class&#xff1a;bean的全類名&#xff0c;通過反射的方式在IOC容器中創建B…

win10升級后chrome碰到對話框就卡死

低版本的 chrome 會出現這樣的問題 解決方法&#xff1a; 設置-------高級設置-----取消硬件加速

客戶端SDK測試思路

本文來自網易云社區作者&#xff1a;萬春艷是什么客戶端SDK是為第三方開發者提供的軟件開發工具包&#xff0c;包括SDK接口、開發文檔和Demo示例等。SDK和應用之間是什么關系呢&#xff1f;以云信即時消息服務為例&#xff0c;如下圖所示&#xff0c;應用客戶端通過調用云信SDK…

nginx could not build the server_names_hash 解決方法

原文地址&#xff1a;http://www.jb51.net/article/26412.htm ------------------------------------------------------- nginx “nginx could not build the server_names_hash”解決方法 給一個服務器下增加了一些站點別名&#xff0c;差不多有20多個。 重啟nginx時候&#…