axios源碼中的10多個工具函數,值得一學~

大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。

本文來自讀者Ethan01投稿,寫了axios源碼中的工具函數~非常值得一學。原文鏈接:https://juejin.cn/post/7042610679815241758

1.前言

歌德說過:讀一本好書,就是在和高尚的人談話。

同理,讀優秀的開源項目的源碼,就是在和牛逼的大佬交流。

之前總覺得閱讀源碼是一件了不起的事情,是只有大佬才會去做的事。其實源碼也不是想象的那么難,至少有很多看得懂。 比如源碼中的工具函數,就算是初級的前端開發也是能夠看懂的。重要的是,要邁出這一步,閱讀源碼沒什么的。

閱讀本文,你將學到:

1、javascript、nodejs調試技巧及調試工具;
2、如何學習調試axios源碼;
3、如何學習優秀開源項目的代碼,應用到自己的項目;
4、axios源碼中實用的工具函數;

2.環境準備

2.1 讀開源項目的貢獻指南

打開 axios[1] , 你會驚奇的發現,這不是在瀏覽器中打開了一個vscode嗎?你沒有看錯,確實是在瀏覽器中打開了vscode,而且還打開了axios的源碼。如果你仔細看了瀏覽器地址欄里的url, 你會發現github后多了1s,顧名思義,就是1s打開github上的項目。一個小擴展:在每一個github項目中的url里直接加上1s,就能在網頁版vscode中查看源碼了(不過貌似現在只能查看,不能調試,調試的話還是要把源碼clone到本地)。

開源項目一般能在根目錄下的README.md文件或CONTRIBUTING.md中找到貢獻指南。貢獻指南中說明了參與貢獻代碼的一些注意事項,比如:代碼風格、代碼提交注釋格式、開發、調試等。

打開CONTRIBUTING.md[2],可以看到在54行的內容:

Running?sandbox?in?browser```bash
$?npm?start
#?Open?127.0.0.1:3000

這里就是告訴我們在如何在瀏覽器中運行項目的。

2.2 克隆項目并運行

這里使用axios的版本是v0.24.0;

git?clone?https://github.com/axios/axios.gitcd?axiosnpm?start打開?http://localhost:3000/

這時候可以看到這么一個頁面:

6406c80fdbdb46ac3db4a30410930dde.png
image.png

打開瀏覽器的控制臺,選中source選項,然后在axios目錄中可以找到源碼,如下圖:

29bb3311799b37771e551eacac913aa7.png
image.png

這個axios.js就是入口文件,這時候就可以隨意打斷點進行調試了。

其實,閱讀所有源碼的流程都類似,之所以說的這么詳細,是為了能夠讓沒有閱讀過源碼的同學也能夠跟著一步一步的閱讀起來。當你讀完之后,肯定會有不少的收獲,把這個過程和收獲記錄下來,慢慢的提升自己,早晚會成為大佬。

3. 工具函數

今天的主角是`utils.js`[3]文件, 以下列出了文件中的工具函數:

3.1 isArray 判斷數組

var?toString?=?Object.prototype.toString;//?可以通過?`toString()`?來獲取每個對象的類型
//?一般返回值是?Boolean?類型的函數,命名都以?is?開頭
function?isArray(val)?{return?toString.call(val)?===?'[object?Array]';
}

3.2 isUndefined 判斷Undefined

//?直接用`typeof`判斷
//?注意?typeof?null?===?'object'
function?isUndefined(val)?{return?typeof?val?===?'undefined';
}

3.3 isBuffer 判斷 buffer

//?先判斷不是?`undefined`和`null`
//?再判斷?`val`存在構造函數,因為`Buffer`本身是一個類
//?最后通過自身的`isBuffer`方法判斷function?isBuffer(val)?{return?val?!==?null?&&?!isUndefined(val)?&&?val.constructor?!==?null?&&?!isUndefined(val.constructor)&&?typeof?val.constructor.isBuffer?===?'function'?&&?val.constructor.isBuffer(val);
}

什么是Buffer?

JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。

但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個Buffer 類,該類用來創建一個專門存放二進制數據的緩存區。詳細可以看 官方文檔[4] 或 更通俗易懂的解釋[5]

因為axios可以運行在瀏覽器和node環境中,所以內部會用到nodejs相關的知識。

3.4 isFormData 判斷FormData

//?`instanceof`?運算符用于檢測構造函數的?`prototype`?屬性是否出現在某個實例對象的原型鏈上function?isFormData(val)?{return?(typeof?FormData?!==?'undefined')?&&?(val?instanceof?FormData);
}//?instanceof?用法function?C()?{}
function?D()?{}const?c?=?new?C()c?instanceof?C?//?output:?true???因為?Object.getPrototypeOf(c)?===?C.prototypec?instanceof?Object?//?output:?true???因為?Object.prototype.isPrototypeOf(c)c?instanceof?D?//?output:?false???因為?D.prototype?不在?c?的原型鏈上

3.5 isObject 判斷對象

//?排除?`null`的情況
function?isObject(val)?{return?val?!==?null?&&?typeof?val?===?'object';
}

3.6 isPlainObject 判斷 純對象

純對象:用{}new Object()創建的對象。

function?isPlainObject(val)?{if?(Object.prototype.toString.call(val)?!==?'[object?Object]')?{return?false;}var?prototype?=?Object.getPrototypeOf(val);return?prototype?===?null?||?prototype?===?Object.prototype;
}//?例子1
const?o?=?{name:?'jay}
isPlainObject(o)?//?true//?例子2
const?o?=?new?Object()
o.name?=?'jay'
isPlainObject(o)???//?true//?例子3
function?C()?{}
const?c?=?new?C()
isPlainObject(c);??//?false//?其實就是判斷目標對象的原型是不是`null`?或?`Object.prototype`

3.7 isDate 判斷Date

function?isDate(val)?{return?Object.prototype.toString.call(val)?===?'[object?Date]';
}

3.8 isFile 判斷文件類型

function?isFile(val)?{return?Object.prototype.toString.call(val)?===?'[object?File]';
}

3.9 isBlob 判斷Blob

function?isBlob(val)?{return?Object.prototype.toString.call(val)?===?'[object?Blob]';
}

Blob 對象表示一個不可變、原始數據的類文件對象。它的數據可以按文本或二進制的格式進行讀取。

3.10 isFunction 判斷函數

function?isFunction(val)?{return?Object.prototype.toString.call(val)?===?'[object?Function]';
}

3.11 isStream 判斷是否是流

//?這里`isObject`、`isFunction`為上文提到的方法
function?isStream(val)?{return?isObject(val)?&&?isFunction(val.pipe);
}

3.12 isURLSearchParams 判斷URLSearchParams

function?isURLSearchParams(val)?{return?typeof?URLSearchParams?!==?'undefined'?&&?val?instanceof?URLSearchParams;
}//?例子
const?paramsString?=?"q=URLUtils.searchParams&topic=api"
const?searchParams?=?new?URLSearchParams(paramsString);
isURLSearchParams(searchParams)?//?true

URLSearchParams 接口定義了一些實用的方法來處理 URL 的查詢字符串,詳情可看 MDN[6]

var?paramsString?=?"q=URLUtils.searchParams&topic=api"
var?searchParams?=?new?URLSearchParams(paramsString);for?(let?p?of?searchParams)?{console.log(p);
}//?輸出?
[?'q',?'URLUtils.searchParams'?]
[?'topic',?'api'?]searchParams.has("topic")?===?true;?//?true
searchParams.get("topic")?===?"api";?//?true
searchParams.getAll("topic");?//?["api"]
searchParams.get("foo")?===?null;?//?true
searchParams.append("topic",?"webdev");
searchParams.toString();?//?"q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic",?"More?webdev");
searchParams.toString();?//?"q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString();?//?"q=URLUtils.searchParams"

3.13 trim 去除首尾空格

//?`trim`方法不存在的話,用正則
function?trim(str)?{return?str.trim???str.trim()?:?str.replace(/^\s+|\s+$/g,?'');
}

3.14 isStandardBrowserEnv 判斷標準瀏覽器環境

function?isStandardBrowserEnv()?{if?(typeof?navigator?!==?'undefined'?&&?(navigator.product?===?'ReactNative'?||navigator.product?===?'NativeScript'?||navigator.product?===?'NS'))?{return?false;}return?(typeof?window?!==?'undefined'?&&typeof?document?!==?'undefined');
}

但是官方已經不推薦使用這個屬性navigator.product

316699b6b380f2566226db93bf6a9818.png
image.png

3.15 forEach 遍歷對象或數組

保留了英文注釋,提升大家的英文閱讀能力。

/***?Iterate?over?an?Array?or?an?Object?invoking?a?function?for?each?item.*??用一個函數去迭代數組或對象**?If?`obj`?is?an?Array?callback?will?be?called?passing*?the?value,?index,?and?complete?array?for?each?item.*?如果是數組,回調將會調用value,?index,?和整個數組**?If?'obj'?is?an?Object?callback?will?be?called?passing*?the?value,?key,?and?complete?object?for?each?property.*?如果是對象,回調將會調用value,?key,?和整個對象**?@param?{Object|Array}?obj?The?object?to?iterate*?@param?{Function}?fn?The?callback?to?invoke?for?each?item*/function?forEach(obj,?fn)?{//?Don't?bother?if?no?value?provided//?如果值不存在,無需處理if?(obj?===?null?||?typeof?obj?===?'undefined')?{return;}//?Force?an?array?if?not?already?something?iterable//?如果不是對象類型,強制轉成數組類型if?(typeof?obj?!==?'object')?{obj?=?[obj];}if?(isArray(obj))?{//?Iterate?over?array?values//?是數組,for循環執行回調fnfor?(var?i?=?0,?l?=?obj.length;?i?<?l;?i++)?{fn.call(null,?obj[i],?i,?obj);}}?else?{//?Iterate?over?object?keys//?是對象,for循環執行回調fnfor?(var?key?in?obj)?{//?只遍歷可枚舉屬性if?(Object.prototype.hasOwnProperty.call(obj,?key))?{fn.call(null,?obj[key],?key,?obj);}}}
}

所以,源碼為什么不用forEachfor...in...呢???????

3.16 stripBOM刪除UTF-8編碼中BOM

/***?Remove?byte?order?marker.?This?catches?EF?BB?BF?(the?UTF-8?BOM)**?@param?{string}?content?with?BOM*?@return?{string}?content?value?without?BOM*/function?stripBOM(content)?{if?(content.charCodeAt(0)?===?0xFEFF)?{content?=?content.slice(1);}return?content;
}

所謂 BOM,全稱是Byte Order Mark,它是一個Unicode字符,通常出現在文本的開頭,用來標識字節序。UTF-8主要的優點是可以兼容ASCII,但如果使用BOM的話,這個好處就蕩然無存了。

4.總結

本文主要介紹了axios源碼的調試過程,以及介紹了一些utils.js中的非常實用的工具函數;相信通過閱讀源碼,日積月累,并把這些代碼或思想應用的自己項目中去,相信能夠很好的提升自己的編碼能力。

come on! worker!

同時也推薦一些好用的工具:

瀏覽器中運行`vscode`, 查看源碼[7]

代碼沙盒,能運行多種語言,且可以添加依賴[8]

vs code 的 code Runner插件[9]

參考資料

[1]

axios: https://github1s.com/axios/axios

[2]

CONTRIBUTING.md: https://github1s.com/axios/axios/blob/HEAD/CONTRIBUTING.md

[3]

utils.js: https://github.com/axios/axios/blob/master/lib/utils.js

[4]

官方文檔: http://nodejs.cn/api/buffer.html#buffer

[5]

更通俗易懂的解釋: https://www.runoob.com/nodejs/nodejs-buffer.html

[6]

MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams

[7]

瀏覽器中運行vscode, 查看源碼: https://github1s.com/axios/axios

[8]

代碼沙盒,能運行多種語言,且可以添加依賴: https://codesandbox.io/

[9]

vs code 的 code Runner插件: https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner


0686776708c31ed9609ec51dad113a54.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

133214fd2211e649fd3de1de4e6f1020.png

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。分享、收藏、點贊、在看我的文章就是對我最大的支持~

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

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

相關文章

安裝jenkins時出現 No such plugin: cloudbees-folder的解決辦法

今天安裝了一下jenkins&#xff0c;在初始化安裝插件時出現“ No such plugin: cloudbees-folder”錯誤&#xff0c;根據網上的教程&#xff1a; 1、打開鏈接“http://ftp.icm.edu.pl/packages/jenkins/plugins/cloudbees-folder/”&#xff0c;在最下面找到并打開“latest”目…

寄充氣娃娃怎么寄_我如何在5小時內寄出新設計作品集

寄充氣娃娃怎么寄Over the Easter break, I challenged myself to set aside an evening rethinking the structure, content and design of my portfolio in Notion with a focus on its 在復活節假期&#xff0c;我挑戰自己&#xff0c;把一個晚上放在一邊&#xff0c;重新思…

基于Hbase的用戶評分協同過濾推薦算法

基于Hbase的用戶評分協同過濾推薦算法 作者&#xff1a; 張保維 2012-1-3 一、 概述 本文為推薦引擎設計的基礎篇&#xff0c;介紹基于hbase 存儲方式用戶評分的方式進行推薦的主體算法及在分布式平臺環境下的實現。由于推薦算法分支眾多&#xff0c;我們先從簡單及實用的算法…

最全 JavaScript Array 方法 詳解

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。我們在日常開發中&#…

[譯] React Hooks: 沒有魔法,只是數組

[譯] React Hooks: 沒有魔法&#xff0c;只是數組 原文鏈接&#xff1a; medium.com/ryardley/r… 我是 React 新特性 Hooks 的粉絲。但是&#xff0c;在你使用 React Hooks的過程中&#xff0c;有一些看上去 很奇怪的限制 。在本文里&#xff0c;對于那些還在為了理解這些限制…

管理溝通中移情的應用_移情在設計中的重要性

管理溝通中移情的應用One of the most important aspects of any great design is the empathetic understanding of and connection to the user. If a design is ‘selfish’, as in when a product designed with the designer in mind and not the user, it will ultimatel…

網易前端進階特訓營,邀你免費入營!一舉解決面試晉升難題!

網易等大廠的前端崗位一直緊缺&#xff0c;特別是資深級。最近一位小哥面進網易&#xff0c;定級P4&#xff08;資深&#xff09;&#xff0c;總包60W&#xff0c;給大家帶來真實面經要點分享。網易的要求有&#xff1a;1.對性能優化有較好理解&#xff0c;熟悉常用調試工具2.熟…

Feign的構建過程及自定義擴展功能

spring-cloud-openfeign-core-2.1.1.RELEASE.jar 中 HystrixFeign 的詳細構建過程&#xff1a; EnableFeignClients -> FeignClientsRegistrar 掃描 Feign注解的類 -> FeignClientFactoryBean通過Targeter生產FeignClient -> Targeter通過Feign.Builder構建Feign ->…

angelica類似_親愛的當歸(Angelica)是第一個讓我哭泣的VR體驗

angelica類似It was a night just like any other night. I finished work for the day and closed my laptop. I had dinner and after an hour, I put on my Oculus Quest headset in order to begin my VR workout.就像其他任何夜晚一樣&#xff0c; 這 是一個夜晚。 我完成…

面試官:請手寫一個帶取消功能的延遲函數,axios 取消功能的原理是什么

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。本文倉庫 https://githu…

關于base64編碼的原理及實現

我們的圖片大部分都是可以轉換成base64編碼的data&#xff1a;image。 這個在將canvas保存為img的時候尤其有用。雖然除ie外&#xff0c;大部分現代瀏覽器都已經支持原生的基于base64的encode和decode&#xff0c;例如btoa和atob。&#xff08;將canvas畫布保存成img并強制改變…

Django web開發系列(五)模板

一 前言在上一節了解到視圖函數處理后&#xff0c;會將結果渲染到創建的html頁面&#xff0c;但html如何接收并顯示視圖函數返回的動態數據呢&#xff1f;最常用的做法就是使用模板(Template)&#xff0c;本節將簡單介紹一下模板的作用和用法。 可以這樣簡單的理解模板的概念&a…

facebook 面試_如何為您的Facebook產品設計面試做準備

facebook 面試重點 (Top highlight)Last month, I joined Facebook to work on Instagram DMs and as a way to pay it forward, I 上個月&#xff0c;我加入了Facebook&#xff0c;從事Instagram DM的工作&#xff0c;作為一種支付方式&#xff0c;我 offered to help anyone…

8年了,開始寫點東西了

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。今天分享一位大佬的文章…

荒徑 弗羅斯特_弗羅斯特龐克,顛覆性城市建設者

荒徑 弗羅斯特Most gamers are familiar with Will Wright’s famous SimCity series. It created the city building genre and there have been many attempts over the years to ape it. But few developers have been bold enough to completely deconstruct the formula; …

2012年1月份第2周51Aspx源碼發布詳情

WP7手指畫圖應用源碼 2012-01-14 [VS2010] 游戲介紹&#xff1a;Windows Phone 7手指畫圖應用 – FingerPaint&#xff0c;您通過此游戲可以隨心畫一些感興趣的東西&#xff0c;陶冶情操。操作簡單&#xff0c;頁面簡潔。適合新手學習參考。 WP7 Car Bloke(交通工具開銷記錄)源…

Gitee 如何自動部署博客 Pages?推薦用這個GitHub Actions!

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。前段時間我把自己的博客…

Java io流學習總結(三)

轉載于&#xff1a;https://www.cnblogs.com/ll409546297/p/7197911.html java.io幾種讀寫文件的方式 一、Java把這些不同來源和目標的數據都統一抽象為數據流。 Java語言的輸入輸出功能是十分強大而靈活的。 在Java類庫中&#xff0c;IO部分的內容是很龐大的&#xff0c;因為它…

現在流行的畫原型圖工具_原型資源圖:8種流行原型工具的綜合指南

現在流行的畫原型圖工具Although tools are not the most important things to learn as a UX designer, inevitably you need to use it in order to achieve your more important goals, to solve user’s problems. This article covers today’s 8 popular UX prototyping …

持續5個月,200+筆記,3千多人參與,邀請你來學源碼~

注意&#xff1a;本文點擊文末閱讀原文可查看文中所有鏈接。我正在參加掘金年度人氣作者投票活動&#xff0c;大家有空可以加微信群幫忙投票&#xff0c;感謝大家&#xff01;想起今天還沒發文&#xff0c;就開放下微信群二維碼&#xff0c;大家掃碼進群讀源碼和幫忙投票吧。群…