Axios构造函数学习笔记

Axios 构造函数

lib/core/axios.js

...
var intercaptorManager = require(./IntercaptorManger);
var dispatchRequest = require(./dispatchRequest);

intercaptorManager 拦截器构造函数,添加拦截器,删除拦截器和拦截器执行

lib/core/IntercaptorManger.js

function IntercaptorManger() {
	this.handlers = [];
}

//在构造函数IntercaptorManger原型上添加use方法 添加对象到handlers中并返回下标
IntercaptorManger.prototype.ues = function use(fulfilled, rejected) {
	this.handlers.push({
		fulfilled: fulfilled,
		rejected: rejected,
	});
	return this.handlers.length - 1; 
}

//在构造函数IntercaptorManger原型上添加eject方法, 移除handlers对应下标的对象
IntercaptorManger.prototype.eject =  function eject(id) {
	if(this.handlers[id]){
		this.handlers[id] = null
	}
}

//在构造函数IntercaptorManger原型上添加forEach方法, 使handles对象一一传参到参数函数fn并执行
IntercaptorManger.prototype.forEach = function forEach(fn) {
	utils.forEach(this.handlers, function forEachHandler(h) {//h表示this.handlers中具体的项
		if(h !== null) {
			fn(h)
		}
	})
}

dispathchRequest

用来处理config和调用默认adaptor的方法,同时做输入输出数据转化

lib/core/dispatchRequest

functuon throwIfCancellationRequest(config) {
	config.cancelToken && config.cancelToken.throwIfRequest();
}
function transformData(data, headers, fns) {
	utils.forEach(fns, function transform(fn) {
		data = fn(data, headers)
	})
}
function dispatchRequest(config) {
	throwIfCancellationRequest(config);
	config.headers = config.headers || {};
	//tansformRequest用在发送数据前修改请求数据,数组类型,单个项为方法
	//单个项方法中接受2个数据分别为config.data 和 config.headers, 必须返回data
	configData = transformData(config.data, config.headers, config.transfromRequest);
	//浅合并通用herders配置,方法headers配置以及自定义headers配置,层级逐渐增高
	config.headers = utils.merge(config.headers.common || {}, config.headers[config.methods] || {}, config.headers);
	//删除config.header[xxx]上的对象,已经合并到config.header上了, 可能并不存在
	utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], function clearHeaderConfig(method) {
		delete config.headers[method]
	})

	var adapter = config.adapter || defaults.adaptar;
	//通过适配器向服务端发送请求,适配器方法返回通过promise包裹了
	return adaptar(config).then(function onAdapterResolution(response) {
		throwIfCancellationRequest(config);
		//tansformResponse用在收到数据后修改响应数据,数组类型,单个项为方法
		response.data = transformData(response.data, response.headers, config.transformResponse);
		return response;
	}, function onAdapterRejection(reason) {
		if(isCancel(reason)){
			throwIfCancellationRequest(config)
			if(reason && reason.response) {
				reason.response.data = transformData(reason.response.data, reson.response.headers, config.transforResponse)
			}
		}
		return promise.reject(reason)
	})
}

Axios 构造函数

lib/core/Axios.js

function Axios(intanceConfig) {
	this.defaults = intanceConfig;
	this.intercaptors = {
		request: new IntercaptorManger(),
		response: new IntercaptorManger(),
	}
}
Axios.prototype.request = function request(config) {
	if(typeof config === 'string'){
		config = arguments[1] || {};
		config.url = arguments[0];
	} else {
		config = config || {};
	}
	config = utils.merge(this.defaults, config);
	//设置默认请方法,并转化为小写
	if(config.method) {
		config.method = config.method.toLowerCase();
	} else if(this.defaults) {
		config.method = this.defaults.method.toLowerCase();
	} esle {
		config.methos = 'get';
	}

	var chain = [dispatchRequest, undefined];
	var promise =  Promise.resolve(config);
	//调用Intercaptors.prototype上的forEach方法,对内部handles进行forEach循环,intercaptor表示this.handles中具体某项
	this.intercaptors.request.forEach(function unShiftRequestIntercaptors(intercaptor) {
		//向数组头部添加一个或者多个参数
		chain.unshif(intercaptor.fulfilled, intercaptor.rejected);
	})
	this.intercaptors.response.forEach(function pushResponseIntercaptors(intercaptor){
		//向数组后面添加一个或者多个参数
		chain.push(intercaptor.fulfilled, intercaptor.rejected);
	})
	while(chain.length) {
		promise = promise.then(chain.shift(), chain.shift())
	}
	return promise;
}

Axios.prototype.grtUri =  function grtUri(config) {
	config = utils.merge(this.defaults, config);
	//地址 参数, 解析方式
	return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/g, '');
}
//给Axios原型上挂在具体请求方法,直接使用axios.xxx调用
//不需要参数的请求方法
utils.forEach(['delete, 'get', 'head', 'options'], function forEachMethodNoData(method) {
	//地址 参数, 默认参数
	Axios.prototype[method] = function(url, config) {
		return this.request(utils.merge(config || {}, {method: method, url: url}))
	}
})
//需要参数的请求方法
utils.forEach(['post', 'put', 'patch'], function forEachMethosWithData(method) {
	Axios.prototype[method] =  function(url, data, config){
		return this.request(utils.merge(config || {}, {method: method, url: url, data: data, }))
	}
})
posted @ 2019-11-13 20:25  zgddan  阅读(364)  评论(0)    收藏  举报