Handwritten axios source code series 2: Create axios function object

Insert image description here
The current chapter officially enters the handwritten axios source code series, and we have to start writing code with real guns.

Because the axios source code has a relatively large amount of code, we only focus on the main thread here to give everyone a general understanding of the main core functions of axios. As for the specific details, you need to read through the axios source code to understand. The handwritten axios source code series only handwrites 4 of the main functional modules, which is in the previous article: Handwritten axios source code series one: axios core knowledge points The four core function points introduced in:

  1. axios function object
  2. dispatchRequest sends a request
  3. interceptors interceptors
  4. cancelToken cancel request

1. Introduction to modular catalog

It is recommended that you download the source code of axios first, and then go through the directory files of the source code. The main files are all in the lib directory. I will not introduce them one by one here.

Insert image description here


Next, let’s take a look at the directory introduction created by my handwritten axios source code (the file name is based on the name of the source code file):

Insert image description here

  • _Axios.js: The constructor of axios. Because there is one axios.js, the file name is not case-sensitive and will be repeated, so a underscore is added< a i=2> Prevent file name duplication; among them, request method is the focus, interceptor function< a i=6>Write here;_Axios
  • adapters.js: Adapter, which has a method getAdapter to get the method of sending the request xhr or http;
  • axios.js: The entry file of the entire directory, creates the axios function object and exposes some properties and methods to the outside world;
  • CancelToken: function code to cancel the request;
  • defaults.js: Default configuration items (preconfigured);
  • dispatchRequest.js: The file directory where the request is actually sent and the response data is received;
  • index.html: Handwritten test code of axios source code to test whether the code you wrote is correct;
  • InterceptorManager: constructor of the interceptor;
  • xhr.js: File directory for writing AJAX (Asynchronous Javascript And XML) code.

2. Create axios function object

1. Create axios.js file

import Axios from "./_Axios.js";
import defaults from "./defaults.js";
import CancelToken from "./CancelToken";

// 初始化 axios 函数对象
function createInstance(defaultConfig){
    
    
	// 生成 _Aixos 的实例对象
	const context = new Axios(defaultConfig);
	// 生成 instance 绑定函数,并且绑定 this 为 context,防止调用时 this 指向不明
	const instance = Axios.prototype.request.bind(context, ...arguments);
	// 将 context 实例对象的属性复制到 instance 上
	Object.keys(context).forEach(key=>{
    
    
		instance[key] = context[key]
	})
	// 将 Axios 原型对象的属性复制到 instance 上
	Object.keys(Axios.prototype).forEach(key=>{
    
    
		instance[key] = Axios.prototype[key]
	})
	// axios.create 方法
	instance.create = function(instanceConfig){
    
    
		const mergeConfig = {
    
    
			...defaultConfig,
			...instanceConfig
		}
		return createInstance(mergeConfig);
	}
	// instance 就是 axios
	return instance;
}
// 创建 axios 函数对象
const axios = createInstance(defaults);
// 对外暴露 CancelToken 类,取消请求时使用
axios.CancelToken = CancelToken;
// 导出 axios
export default axios;

2. Create defaults.js file

export default {
    
    
	// 适配器的默认配置,写适配器 adapters 代码时需要传入的配置
	adapter: ['xhr', 'http']
}

3. Create the _Axios.js file

import InterceptorManager from "./IntercptorManager.js";
import dispatchRequest from "./dispatchRequest.js";

export default class Axios {
    
    
	constructor(config){
    
    
		// 实例对象的 defaults属性(默认配置对象)
		this.defaults = config;
		// 实例对象的 interceptors属性(拦截器)
		this.interceptors = {
    
    
			request: new InterceptorManager(),
			response: new InterceptorManager()
		}
	}
	// request 发送请求
	request(configOrUrl, config){
    
    
		// 判断 configOrUrl是否为 url地址
		if(typeof configOrUrl === "string"){
    
    
			config.url = configOrUrl
		} else {
    
    
			config = {
    
    
				...configOrUrl,
				...config
			}
		}
		// 将 config包装为一个成功状态的 promise对象
		let promise = Promise.resolve(config);
		// 创建执行链,这里调用 dispatchRequest方法以发送请求
		const chain = [dispatchRequest, undefined];
		// 调用 promise.then()将 config传入 dispatchRequest中,dispatchRequest中返回的也是一个 prommise对象
		promise = promise.then(chain[0], chain[1]);
		// 发送请求后返回的是一个 promise对象
		return promise;
	}
}
const methodsWithNoData = ["delete", "get", "head", "options"];
const methodsWithData = ["post", "put", "patch"];
// 给 Axios的原型对象添加请求方法
methodsWithNoData.forEach(method => {
    
    
	Axios.prototype[method] = function(url, config){
    
    
		config = {
    
     ...config, method, url };
		// 最后返回 request生成的 promise对象
		return this.request(config)
	}
})
methodsWithData.forEach(method => {
    
    
	Axios.prototype[method] = function(url, data, config){
    
    
		config = {
    
     ...config, method, url, data };
		return this.request(config)
	}
})

4. Summary

The above code contains the creation process of axios function object:

  1. Use createInstance() to generate axios function object
    • First instantiate the object context, and then use the Axios.prototype.request method to bind a new function instance. Calling instance() is equivalent to calling Axios.prototype.request();< /span>
    • The generated new function instance does not have any properties and methods to use, so the properties and methods on context and Axios.prototype are copied to the instance for use;
    • mounts a create method for use by axios packaging. Calling the create() method is actually calling the createInstance() method.
  2. Mount other properties for axios and expose them for external use.
  3. Export axios function object.

In the next article we will focus on dispatchRequest and adapter adapters.

Guess you like

Origin blog.csdn.net/ThisEqualThis/article/details/130313755