您现在的位置是:首页 >其他 >手写axios源码系列三:dispatchRequest发送请求网站首页其他
手写axios源码系列三:dispatchRequest发送请求
简介手写axios源码系列三:dispatchRequest发送请求
上篇文章中介绍了创建 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或者 http
const 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 这里的代码逻辑还是比较简单,比较清晰的。
用一张图来表示可能更直观一些:
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。