axios source code in more than 10 tool functions, worth learning~

This article is contributed by reader Ethan01, who wrote the tool function in the axios source code ~ which is very worth learning. Original link: https://juejin.cn/post/7042610679815241758

1. Preface

Goethe said: reading a good book is talking to noble people.

Similarly, reading the source code of excellent open source projects is to communicate with the big guys.

Before, I always thought that reading the source code was a great thing, which only big guys would do. In fact, the source code is not as difficult as expected, at least many can understand it. For example, the tool functions in the source code can be understood even in the primary front-end development. It is important to take this step by reading the source code.

After reading this article, you will learn:

1,javascript,nodejs Debugging skills and tools;
2,How to learn debugging axios Source code;
3,How to learn the code of excellent open source projects and apply it to their own projects;
4,axios Practical tool functions in the source code;

2. Environmental preparation

2.1 read the contribution guide of open source projects

Open axios[1], you will be surprised to find that this is not a vscode opened in the browser? You're right. You really opened vscode in the browser and the source code of axios. If you look closely at the url in the browser address bar, you will find that there is 1s after github. As the name suggests, 1s opens the project on github. A small extension: add 1s directly to the url of each github project to view the source code in the web version of vscode (but it seems that you can only view it now and can't debug it. If you debug, you still have to clone the source code locally).

Open source projects can generally be found in readme. Com under the root directory MD file or configuring Find the contribution guide in MD. The contribution guide explains some precautions for participating in contributing code, such as code style, code submission comment format, development, debugging, etc.

Open configuring MD [2], you can see the content in line 54:

Running sandbox in browser

```bash
$ npm start
# Open 127.0.0.1:3000

Here is how to run the project in the browser.

2.2 clone the project and run it

The version of axios used here is v0 24.0;

git clone https://github.com/axios/axios.git

cd axios

npm start

open http://localhost:3000/

At this time, you can see such a page:

image.png

Open the browser console, select the source option, and then find the source code in the axios directory, as shown in the following figure:

image.png

This Axios JS is the entry file. At this time, you can break the point at will for debugging.

In fact, the process of reading all source codes is similar. The reason why it is so detailed is to enable students who have not read the source code to read step by step. When you finish reading, you will certainly have a lot of harvest. Record this process and harvest, slowly improve yourself and become a big man sooner or later.

3. Tool function

Today's protagonist is ` utils JS ` [3] file. The tool functions in the file are listed below:

3.1 isArray judgment array

var toString = Object.prototype.toString;

// You can get the type of each object through 'toString()'
// Generally, the return value is a Boolean function, and the name starts with is
function isArray(val) {
  return toString.call(val) === '[object Array]';
}

3.2 isUndefined judgment

// Judge directly with 'typeof'
// Note typeof null = = 'object'
function isUndefined(val) {
  return typeof val === 'undefined';
}

3.3 is buffer judgment

// First judge whether it is not 'undefined' or 'null'`
// Then judge that 'val' has a constructor because 'Buffer' itself is a class
// Finally, judge through its own 'isBuffer' method

function isBuffer(val) {
  return val !== null 
          && !isUndefined(val) 
          && val.constructor !== null 
          && !isUndefined(val.constructor)
          && typeof val.constructor.isBuffer === 'function' 
          && val.constructor.isBuffer(val);
}

What is Buffer?

The JavaScript language itself has only string data types, not binary data types.

However, binary data must be used when processing streams such as TCP streams or file streams. Therefore, in node JS, a Buffer class is defined, which is used to create a cache for storing binary data. For details, please refer to the official document [4] or more understandable explanation [5].

Because axios can run in the browser and node environment, nodejs related knowledge will be used internally.

3.4 isFormData judgment

// `The instanceof operator is used to detect whether the 'prototype' attribute of the constructor appears on the prototype chain of an instance object

function isFormData(val) {
  return (typeof FormData !== 'undefined') && (val instanceof FormData);
}


// instanceof usage

function C() {}
function D() {}

const c = new C()

c instanceof C // output: true because object getPrototypeOf(c) === C.prototype

c instanceof Object // output: true because object prototype. isPrototypeOf(c)

c instanceof D // output: false because D.prototype is not on the prototype chain of c

3.5 judgment object of isobject

// Exclude 'null'
function isObject(val) {
  return val !== null && typeof val === 'object';
}

3.6 isplanobject judging pure objects

Pure object: an object created with {} or 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;
}


// Example 1
const o = {name: 'jay}
isPlainObject(o) // true

// Example 2
const o = new Object()
o.name = 'jay'
isPlainObject(o)   // true

// Example 3
function C() {}
const c = new C()
isPlainObject(c);  // false

// In fact, it is to judge whether the prototype of the target object is' null 'or' object prototype`

3.7 isDate judgment Date

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

3.8 isFile judging file type

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

3.9 isBlob judgment

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

A Blob object represents an immutable, raw data class file object. Its data can be read in text or binary format.

3.10 isFunction judgment function

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

3.11 isStream to judge whether it is a stream

// Here, 'isObject' and 'isFunction' are the methods mentioned above
function isStream(val) {
  return isObject(val) && isFunction(val.pipe);
}

3.12 isURLSearchParams judge URLSearchParams

function isURLSearchParams(val) {
  return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
}


// example
const paramsString = "q=URLUtils.searchParams&topic=api"
const searchParams = new URLSearchParams(paramsString);
isURLSearchParams(searchParams) // true

The URLSearchParams interface defines some practical methods to process URL query strings. See MDN[6] for details:

var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);

for (let p of searchParams) {
  console.log(p);
}

// output 
[ '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 remove leading and trailing spaces

// `If the trim ` method does not exist, use regular
function trim(str) {
  return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
}

3.14 isStandardBrowserEnv judgment standard browser environment

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

However, the use of this attribute navigator has been officially deprecated product.

image.png

3.15 forEach traversal object or array

English notes are retained to improve everyone's English reading ability.

/**
 * Iterate over an Array or an Object invoking a function for each item.
 *  Use a function to iterate over an array or object
 *
 * If `obj` is an Array callback will be called passing
 * the value, index, and complete array for each item.
 * If it is an array, the callback will call value, index, and the entire array
 *
 * If 'obj' is an Object callback will be called passing
 * the value, key, and complete object for each property.
 * If it is an object, the callback will call value, key, and the whole object
 *
 * @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 the value does not exist, no processing is required
  if (obj === null || typeof obj === 'undefined') {
    return;
  }

  // Force an array if not already something iterable
  // If it is not an object type, it is forced to be converted to an array type
  if (typeof obj !== 'object') {
    obj = [obj];
  }

  if (isArray(obj)) {
    // Iterate over array values
    // Is an array, and the for loop executes the callback fn
    for (var i = 0, l = obj.length; i < l; i++) {
      fn.call(null, obj[i], i, obj);
    }
  } else {
    // Iterate over object keys
    // Is an object, and the for loop executes a callback fn
    for (var key in obj) {
       // Only enumerable properties are traversed
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        fn.call(null, obj[key], key, obj);
      }
    }
  }
}

So why not use forEach and for in... What about you???????

3.16 stripBOM delete BOM in UTF-8 code

/**
 * 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;
}

The full name of the so-called BOM is Byte Order Mark. It is a Unicode character that usually appears at the beginning of the text to identify the byte order. The main advantage of UTF-8 is that it can be compatible with ASCII, but this advantage will disappear if BOM is used.

4. Summary

This paper mainly introduces the debugging process of axios source code and some utils JS is a very practical tool function; I believe that I can improve my coding ability by reading the source code, accumulating over time, and applying these codes or ideas to my own projects.

come on! worker!

Some useful tools are also recommended:

Run 'vscode' in the browser to view the source code [7]

Code sandbox, which can run multiple languages and add dependencies [8]

code Runner plug-in for vs code [9]

reference material

[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] Official documents: http://nodejs.cn/api/buffer.html#buffer

[5] More understandable explanation: https://www.runoob.com/nodejs/nodejs-buffer.html

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

[7] Run vscode in the browser to view the source code: https://github1s.com/axios/axios

[8] Code sandbox, which can run multiple languages and add dependencies: https://codesandbox.io/

[9] code Runner plug-in for vs Code: https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner

Added by Rommeo on Sat, 25 Dec 2021 20:22:56 +0200