手写axios源码系列二:创建axios函数对象

这篇具有很好参考价值的文章主要介绍了手写axios源码系列二:创建axios函数对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

手写axios源码系列二:创建axios函数对象
当前篇章正式进入手写 axios 源码系列,我们要真枪实弹的开始写代码了。

因为 axios 源码的代码量比较庞大,所以我们这里只抓主线,让大家对 axios 的主要核心功能有个大概了解,至于具体的细节深入,需要大家去通读 axios 源码了解。手写 axios 源码系列只将其中的4个主要功能模块进行了手写,就是在上篇文章: 手写axios源码系列一:axios核心知识点 中介绍的四个核心功能点:

  1. axios 函数对象
  2. dispatchRequest 发送请求
  3. interceptors 拦截器
  4. cancelToken 取消请求

一、模块化目录介绍

建议大家先下载 axios 的源码,然后过一遍源码的目录文件,主要文件全部在 lib 目录下,这里我就不一一介绍了。

手写axios源码系列二:创建axios函数对象


接下来看一下我手写 axios 源码所创建的目录介绍(文件名称依据源码文件名称命名):

手写axios源码系列二:创建axios函数对象

  • _Axios.js:axios的构造函数,因为有一个 axios.js,文件名不区分大小写会重复,所以添加了下横杠 _Axios 防止文件名重复;其中 request 方法为重点,拦截器功能在这里书写;
  • adapters.js:适配器,其中有一个方法 getAdapter 来获取发送请求的方式 xhr 或者 http ;
  • axios.js:整个目录的入口文件,创建了axios 函数对象以及对外暴露了一些属性以及方法;
  • CancelToken:取消请求的功能代码;
  • defaults.js:默认配置项(预配置);
  • dispatchRequest.js:真正发送请求以及接收响应数据的文件目录;
  • index.html:手写axios源码的测试代码,测试一下自己写的代码是否正确;
  • InterceptorManager:拦截器的构造函数;
  • xhr.js:书写 AJAX(Asynchronous Javascript And XML) 代码的文件目录。

二、创建 axios 函数对象

1、创建 axios.js 文件

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、创建 defaults.js 文件

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

3、创建 _Axios.js 文件

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、总结

以上代码包含了 axios 函数对象的创建过程:

  1. 使用 createInstance() 生成 axios 函数对象
    • 先实例化对象 context,然后使用 Axios.prototype.request 方法 bind 一个新函数 instance,调用 instance() 就相当于调用 Axios.prototype.request()
    • 生成的新函数 instance 没有任何属性以及方法可以使用,所以将 context 以及 Axios.prototype 上的属性以及方法复制给 instance 使用;
    • 挂载一个 create 方法,供 axios 封装使用,调用 create() 方法其实就是调用 createInstance() 方法。
  2. 为 axios 挂载其他属性,对外暴露以供使用。
  3. 导出 axios 函数对象。

下篇文章我们着重讲解发送请求 dispatchRequest 以及适配器 adapters文章来源地址https://www.toymoban.com/news/detail-422665.html

到了这里,关于手写axios源码系列二:创建axios函数对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM源码剖析之Java对象创建过程

    关于 \\\"Java的对象创建\\\" 这个话题分布在各种论坛、各种帖子,文章的水平参差不齐。并且大部分仅仅是总结 \\\"面试宝典\\\" 的流程,小部分就是copy其他帖子,极少能看到拿源码作为论证。所以特意写下这篇文章。 版本信息如下: 首先把总结图放在这。接下来分析源码~  用一个

    2024年02月12日
    浏览(38)
  • 从0-1优化C++类对象创建资源消耗 (附源码)

    本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项目中拿来就用的效果,这样更好的服务于工作实践。 专栏介绍:专栏讲本人近10年后端开发常用的案例,以高质量的代码提取出来,并对其进行了介绍。代码拿去

    2023年04月13日
    浏览(30)
  • 【Mybatis源码】XMLConfigBuilder构建器 - 加载XML与创建Configuration对象的过程

    XMLConfigBuilder是Mybatis中定义的进行构建Configuration对象的类,此类用于读取XML配置文件创建并初始化Configuration对象;本篇我们主要介绍加载XML文件与创建Configuration对象的过程。 下面是从Configuration类中取到的代码片段:

    2024年02月08日
    浏览(31)
  • [设计模式Java实现附plantuml源码~创建型] 对象的克隆~原型模式

    前言: 为什么之前写过Golang 版的设计模式,还在重新写 Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那

    2024年01月23日
    浏览(29)
  • 4.是人就能学会的Spring源码教程-IOC容器创建Bean对象

    我们要关注一个接口 BeanFactory ,它是Spring IOC容器的根接口,也是容器的入口。 类的描述中已经清楚的说明了: 我们来看一下这个接口里面的方法。 我们可以看到有各种各样的 getBean 方法,让我们可以从容器中获取到各种各样的Bean对象。 BeanFactory 有一个实现类 DefaultListab

    2024年02月05日
    浏览(29)
  • STM32F4系列单片机库函数模板工程创建

    目录 一、工程配置 1、新建工程 2、芯片选择 3、工程子文件夹创建 (1)FWLIB文件夹添加文件 (2)CORE文件夹添加文件 (3)USER文件夹添加文件 4、工程设置 (1)工程中添加文件夹 (2)工程文件夹中添加配置文件 ①FWLIB文件夹添加文件 ②CORE文件夹添加文件 ③USER文件夹添加

    2024年01月25日
    浏览(35)
  • Apache Doris 聚合函数源码阅读与解析|源码解读系列

    笔者最近由于工作需要开始调研 Apache Doris,通过阅读聚合函数代码切入 Apache Doris 内核,同时也秉承着开源的精神,开发了 array_agg 函数并贡献给社区。笔者通过这篇文章记录下对源码的一些理解,同时也方便后面的新人更快速地上手源码开发。 聚合函数,顾名思义,即对一

    2024年01月25日
    浏览(30)
  • [设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式

    前言: 为什么之前写过Golang 版的设计模式,还在重新写 Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那

    2024年01月19日
    浏览(44)
  • C++实战Opencv第二天——色彩空间转换函数和opencv中图像对象创建与赋值(从零开始,保姆教学)

    OpenCV是一个强大的计算机视觉库,使用C++作为主要编程语言,对于图像处理和计算机视觉领域具有重要意义。其提供了丰富的功能和算法,使得开发者能够快速实现各种图像处理和计算机视觉应用。OpenCV C++为图像处理和计算机视觉领域的开发者提供了一个高效、稳定的工具。

    2024年02月20日
    浏览(32)
  • leetcode — JavaScript专题(五):计数器 II、只允许一次函数调用、 创建 Hello World 函数、将对象数组转换为矩阵、节流、分块数组

    专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷 题面 请你写一个函数 createCounter. 这个函数接收一个初始的整数值 init 并返回一个包含三个函数的对象。 这三个函数是: increment() 将当前值加 1 并返回。 decrement() 将当前值减 1 并返回。 reset() 将当前值

    2024年02月03日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包