'use strict';
//开启严格模式
var utils = require('…/utils'); //导入工具函数
// 这个函数专门用来合并配置项
module.exports = function mergeConfig(config1, config2) {
// config2 如果没有传默认就是一个空的对象
config2 = config2 || {};
// 声明一个新的对象
var config = {};
// 取出config2中的关键Key
var valueFromConfig2Keys = ['url', 'method', 'data'];
// 如果有一些比较深层次的属性也会进行合并 //这些字段有个特点 其值都不是一个单纯的值,二十引用 类型的对象
var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];
// 这些是用户可以手动设置的配置项
var defaultToConfig2Keys = [
'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',
'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',
'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'
];
// 这个是可以自定义的合法响应码
var directMergeKeys = ['validateStatus'];
// 定义一个函数 用来合并两个对象 target source
function getMergedValue(target, source) {
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
return utils.merge(target, source);
} else if (utils.isPlainObject(source)) {
return utils.merge({}, source);
} else if (utils.isArray(source)) {
return source.slice();
}
return source;
}
// 这个函数接受一个参数数 字面意思来看应该是一个属性
function mergeDeepProperties(prop) { //合并深层次的属性的
// config1 = { headers: { } } config2 = { headers : { }}
// {name : { age: { 1 : 2 } }} { name : { key:value }}
// { }
if (!utils.isUndefined(config2[prop])) {
config[prop] = getMergedValue(config1[prop], config2[prop]); //这个应该是合并像 headers这中情况
} else if (!utils.isUndefined(config1[prop])) {
config[prop] = getMergedValue(undefined, config1[prop]);
}
}
utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
if (!utils.isUndefined(config2[prop])) {
// 这一步是将config2 中的配置对象 但凡有 data method url 的进行一个克隆 并同步到config这个终极配置对象上
config[prop] = getMergedValue(undefined, config2[prop]);
} //这一步乍一看挺难,其实就只是把 data url method 加到了config身上而已,仅此而已
});
utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);
// headers 这一步确实可以将诸如headers这类的特殊对象进行一个合并 并且是克隆式合并
//下面的遍历是处理一些默认配置对象的合并
utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
if (!utils.isUndefined(config2[prop])) {
config[prop] = getMergedValue(undefined, config2[prop]); //这一步其实就是把默认配置对 象中的key value放在config之中而已
} else if (!utils.isUndefined(config1[prop])) {
config[prop] = getMergedValue(undefined, config1[prop]); //反正默认的和程序媛自己配置的 只要有一个有就将其挂在到config身上一个不落
}
});
// valiteStatus
utils.forEach(directMergeKeys, function merge(prop) {
if (prop in config2) {
config[prop] = getMergedValue(config1[prop], config2[prop]);
} else if (prop in config1) {
config[prop] = getMergedValue(undefined, config1[prop]);
}
});
var axiosKeys = valueFromConfig2Keys
.concat(mergeDeepPropertiesKeys)
.concat(defaultToConfig2Keys)
.concat(directMergeKeys); //这是一个巨大个的数组 几乎包含所有axios的默认配置key
var otherKeys = Object
.keys(config1)
.concat(Object.keys(config2)) //这个得到的是一个数组 几乎包含所有用户自己的配置
.filter(function filterAxiosKeys(key) { //并将这个数组进行过滤
return axiosKeys.indexOf(key) === -1; //只会返回axiosKey巨大数组中没有的配置项
});
utils.forEach(otherKeys, mergeDeepProperties); //这是为了防止一些用户自定义的配置么
return config; //最终的这个config 是一个标标准准的最终配置对象,并且经进行了深度合并以及属于深刻克隆性质的合并
}