知食记
搜索文档…
适配器模式
axios 的核心逻辑中,我们可以注意到实际上派发请求的是 dispatchRequest 方法。该方法内部其实主要做了两件事:
    1.
    数据转换,转换请求体/响应体,可以理解为数据层面的适配;
    2.
    调用适配器。
调用适配器的逻辑如下:
1
// 若用户未手动配置适配器,则使用默认的适配器
2
var adapter = config.adapter || defaults.adapter;
3
4
// dispatchRequest方法的末尾调用的是适配器方法
5
return adapter(config).then(function onAdapterResolution(response) {
6
// 请求成功的回调
7
throwIfCancellationRequested(config);
8
9
// 转换响应体
10
response.data = transformData(
11
response.data,
12
response.headers,
13
config.transformResponse
14
);
15
16
return response;
17
}, function onAdapterRejection(reason) {
18
// 请求失败的回调
19
if (!isCancel(reason)) {
20
throwIfCancellationRequested(config);
21
22
// 转换响应体
23
if (reason && reason.response) {
24
reason.response.data = transformData(
25
reason.response.data,
26
reason.response.headers,
27
config.transformResponse
28
);
29
}
30
}
31
32
return Promise.reject(reason);
33
});
Copied!
大家注意注释的第一行,“若用户未手动配置适配器,则使用默认的适配器”。手动配置适配器允许我们自定义处理请求,主要目的是为了使测试更轻松。
实际开发中,我们使用默认适配器的频率更高。默认适配器在axios/lib/default.js里是通过getDefaultAdapter方法来获取的:
1
function getDefaultAdapter() {
2
var adapter;
3
// 判断当前是否是node环境
4
if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
5
// 如果是node环境,调用node专属的http适配器
6
adapter = require('./adapters/http');
7
} else if (typeof XMLHttpRequest !== 'undefined') {
8
// 如果是浏览器环境,调用基于xhr的适配器
9
adapter = require('./adapters/xhr');
10
}
11
return adapter;
12
}
Copied!
我们再来看看 Node 的 http 适配器和 xhr 适配器大概长啥样:
http 适配器:
1
module.exports = function httpAdapter(config) {
2
return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) {
3
// 具体逻辑
4
}
5
}
Copied!
xhr 适配器:
1
module.exports = function xhrAdapter(config) {
2
return new Promise(function dispatchXhrRequest(resolve, reject) {
3
// 具体逻辑
4
}
5
}
Copied!
具体逻辑啥样,咱们目前先不关心,有兴趣的同学,可以狠狠地点这里阅读源码。咱们现在就注意两个事儿:
    两个适配器的入参都是 config;
    两个适配器的出参都是一个 Promise。
最近更新 1yr ago
复制链接