2

Axios is a promise-based network request library for node.js and browsers. It is isomorphic (ie the same set of code can run in the browser and node.js ). On the server side it uses the native node.js http module, while on the client side (browser) it uses XMLHttpRequests .

From the official introduction of Axios, we can know that this is a network request library that can run on the browser client + Node server at the same time. When the browser is running, use XMLHttpRequests build requests, and use node 's http module to build the network Node ask.

Today, we have around axios source to achieve interpretation, interpretation completed, and then implement a simple axios library.

Let's first take a look at the project directory structure of the axios (As shown below)

image

Two pieces of information can be obtained from the above figure:

  1. axios core document is lib/axios , so if we focus only on axios words runtime, just look at lib file to this directory.
  2. axios run only rely on a third-party library follow-redirects , this library is used to treat HTTP redirect requests, axios default behavior is to follow the redirect, you can use this library to do guess is redirected to follow. - If you don't want to automatically follow redirects, you need to explicitly declare maxRedirects=0 .

I have not found Baidu axios official document, so here posted a Axios official document , we can use and reference.

lib/axios

Let's open the lib/axios.js file and take a look. (As shown below)

image

Just focus on these few core lines.

|Lines|Description|
| ---- | ---- |
| The first 26 row | document axios.create call is createInstance function that will create a new Axios example |
| Line 34 | Created a default instance axios
| Line 37 ~ 52 | The default axios instance adds a number of properties and methods |
| Line 57 | Export the axios

Axios

Next, let's take a look at the Axios class, which is axios source code, located in lib/core/Axios.js .

function Axios(instanceConfig) {
  this.defaults = instanceConfig;
  this.interceptors = {
    request: new InterceptorManager(),
    response: new InterceptorManager()
  };
}

Axios receives the configuration and stores the instanceConfig configuration in the axios.defaults attribute for subsequent requests.

At the same time, InterceptorManager used to manage request interceptors and response interceptors. We will talk about this interception manager later - InterceptorManager .

axios default instance of lib/defaults.js will be created using the configuration in 061dab939ba7be.

From Axios , we know the reason for this part of the document about modifying the configuration. (As shown below)

image

We can also see Axios example is axios for network requests - the minimum unit of default configurations and is not shared by all instances the presence of a "global default."

But we can do it in two ways.

One of the methods is that we write two sets of configurations, a set of global default configuration and a set of personalized configuration of each instance, which are manually merged when axios

Of course, there is a smarter method, let's take a look at the createInstance method of the previous P1.

function createInstance(defaultConfig) {
  var context = new Axios(defaultConfig);
  var instance = bind(Axios.prototype.request, context);
  
  //...

  instance.create = function create(instanceConfig) {
    // 这里通过闭包继承了 defaultConfig 配置,新创建的实例会继承原实例的配置
    return createInstance(mergeConfig(defaultConfig, instanceConfig));
  };

  return instance;
}

As can be seen from the code, the createInstance method internally inherits the defaultConfig configuration through the closure, and the newly created instance will inherit the configuration of the original instance.

In this case, we can also create a axios instance with a set of global default configuration, and then use this axios instance to call the axios/instance.create method to create other axios instances, so that all axios instances can inherit the global default configuration.

Intercept Manager - InterceptorManager

Let's now take a look at the intercept manager axios InterceptorManager . (As shown below)

image

InterceptorManager is quite simple. There is a handlers array inside, which stores all interceptors registered use

use method returns handlers.length - 1 as the interceptor id. When the eject method is called, the interceptor corresponding to the ID subscript is set to null .

forEach method traverses all interceptor methods, executes the incoming fn callback function, and passes the interceptor as a parameter to fn .

It can be seen from this that the division of responsibilities within axios InterceptorManager only responsible for collecting and managing interceptors, and does not care about the execution logic of interceptors.

However, I feel forEach method is somewhat redundant. If I designed it, I might only expose a getter method to allow external access to handlers . The author's design here may have some other considerations, which I haven't thought of yet.

request

Next, let's take a look at Axios class, that is, the request method, and axios to initiate real network requests through the request

This piece of code is relatively long, and I will parse this large piece of code line by line. request of interceptors and requests in the 061dab939baa1c method is very elegant, and I will focus on it.

The relatively simple part is introduced directly by the table (below)

image

|Lines|Description|
| ---- | ---- |
|Line 32 ~ 41 | Determine the first parameter, assemble the config configuration, and prohibit requests url
|Line 46 ~ 52 | Set the request method, if not declared use the default configured request method, if not set the default request method use get request|

Next, we will focus on interceptor. Let's first look at the request interceptor.

image

There are two parameters that are not described in the documentation, here we explain:

  • Line 58 : When using use register the interceptor, the options.runWhen method in the third parameter will be called first. If the method returns false , the request interceptor will be skipped.
  • Line 62 : When using use register the interceptor, the options.synchronous parameter in the third parameter will explicitly declare that the interceptor is synchronous, otherwise the default is asynchronous interceptor, which will be called promise —— In fact, I think this parameter is meaningless, just asynchronously. Maybe the author also considered some other synchronization scenarios, which I haven't thought of yet.

Important note: Line 64 uses the unshift method to add the request interceptor requestInterceptorChain in the reverse order of registration for subsequent execution.

This also means that the request interceptor modifies the same configuration, and the interceptor added later cannot override the previous interceptor.

Let's take a look at the following request interceptor case.

image

The interceptor set later does not seem to take effect. We can see it after reading the source code. In fact, it is caused by the execution order.

The reason for this design of axios request interceptor from causing the configuration to be overwritten by subsequent processors. - But this point is not stated in the documentation. If you happen to encounter such a scenario, it will inevitably cause some confusion.

The response interceptor is much simpler, I believe I should not need to explain more. (As shown below)

image

It is worth noting that the interceptor adds both success handling and error handling to the internal interceptor array, which means that the inside of the array looks like this:

['Interceptor processing function successfully', 'Interceptor error processing function', 'Interceptor processing successfully processing function', 'Interceptor error processing function', ...]

Understanding this data structure is helpful for the realization of the last piece of core code (as shown below)

image

We need to parse each line of code line by line:

|Lines|Description|
| ---- | ---- |
| Line 74 | Determine whether it is an asynchronous request interceptor (default: yes) |
| The first 75 line | statement chain array, the first element of the array is a method of initiating the request (can be simply understood as fetch method), the second element is to 82 lines make up the undefined |
| Line 77 | Add all request interceptors to the beginning of chain
| Line 78 | Adds all response interceptors to the tail position of chain
| Line 80 ~ 83 | Use config build the first Promise , and then execute chain in sequence - request interceptor -> real request -> response interceptor, each execution passes in resolve ) and failure handlers (as reject ) |

Last paragraph chain execution, very elegant explained axios workflow inside, which is request interceptor -> real request -> response interceptors that a core set of workflows.

It is recommended that you take a closer look at the processing of the last function, and take a closer look.

There is also a paragraph about synchronous request interceptor, which is basically the same. Interested children's shoes can read it by themselves.

summary

Well, here, the basic structure and core workflow of axios

In the next chapter, I will real request of dispatchRequest - 061dab939bae35 in detail, please continue to pay attention.

one last thing

If you have seen this, I hope you will give a like and go~

Your likes are the greatest encouragement to the author, and can also allow more people to see this article!

If you think this article is helpful to you, please help to light up star github to encourage it!


晒兜斯
1.8k 声望534 粉丝