手写axios源码系列三:dispatchRequest发送请求
文章目录
- 一、dispatchRequest 发送请求代码设计思路
-
- 1、创建 dispatchRequest.js 文件
- 2、创建 adapters.js 文件
- 3、创建 xhr.js 文件
- 4、总结
上篇文章中介绍了创建 axios 函数对象的思路,在 Axios 的原型对象上声明了一个 request 方法,在 request 方法中调用了 dispatchRequest 用来发送请求。
现在,让我们来看看 dispatchRequest 发送请求的代码设计思路。
一、dispatchRequest 发送请求代码设计思路
1、创建 dispatchRequest.js 文件
import adapters from "./adapters.js";
import defaults from "./defaults.js"; // {adapter:["xhr","http"]}export default function dispatchRequest(config){// 使用 adapters.getAdapter() 获取发送请求的方式 xhr或者 httpconst adapter = adapters.getAdapter(config.adapter || defaults.adapter);// 返回一个新的 promise对象return adapter(config).then(response => {// 返回响应数据return response;}, error => {throw new Error(error);})
}
2、创建 adapters.js 文件
import xhrAdapter from "./xhr.js";
// import httpAdapter from "./http.js"; // http为 nodejs支持发送的方式,此处不做讨论// 此处维护一个已知适配器对象
const knownAdapters = {// http: httpAdapter,xhr: xhrAdapter
}
export default const adapters = {// 返回一个通信方式适配器getAdapter: (adapters) => {// 兼容性判断:是否为数组adapters = Array.isArray(adapters) ? adapters : [adapters];let adapter;// 获取 xhr 适配器for(let i = 0; i < adapters.length; i++){adapter = knownAdapters[adapters[i]];break;}// adapter 应为一个函数,否则抛出错误if (typeof adapter !== "function"){ throw new TypeError('adapter is not a function');}return adapter;}
}
3、创建 xhr.js 文件
使用 XMLHttpRequest 创建一个 AJAX 请求函数,因为在 dispatchRequest.js 中使用 promise.then(),所以需要返回一个 promise 对象。
以下是一个创建 AJAX 请求的函数 xhrAdapter。
export default function xhrAdapter(config){// 返回一个 promise对象return new Promise((resolve, reject) => {// 创建一个xhr对象const request = new XMLHttpRequest();// 请求资源的地址以及方法,true为异步方式,也是默认方式,可省略request.open(config.url, config.method, true);// 判断请求状态request.onreadystatechange = function(){if (request.readyState === 4){if (request.status >= 200 && request.status < 300){// 反序列化(将响应数据从字符串转换为对象)const responseData = JSON.parse(request.responseText)// 结构化最终结果const response = {data: responseData, // 响应体status: request.status, // 响应状态statusText: request.statusText, // 响应状态描述headers: request.getAllResponseHeaders(), // 响应头config, // 配置项request // xhr请求对象}// 返回最终结果resolve(response)} else {// 响应状态不为 2xx 时,报错reject(new Error(`请求失败!状态码为${request.status}`))}}}// 发送请求request.send(config.data || null);})
}
4、总结
dispatchRequest 这里的代码逻辑还是比较简单,比较清晰的。
用一张图来表示可能更直观一些: