前言
虽然现在angular.js已经不怎么流行,也逐渐被react,vue等主流框架取代,但是angular.js中的一些
设计我觉得非常值得学习,我们不仅仅要跟随潮流,也得了解曾经优秀流行的框架是怎么设计的,为什么要这么
设计,这样我觉得学习新技术才会思路更清晰,才能更快上手。
我们在工作中为了尽快完成领导交给我们的任务不得不去熟悉使用现有框架提供给我们的福利,
却忽略了基础知识或者说底层技术的掌握,框架就是把各种基础函数和技术封装好让软件开发的效率提升,所以现在我们的很多开发人员只停留在使用层面却
不去想这个功能建立在哪些基础知识点上,
$http简介
先来看官方文档的简介:
The $http service is a core AngularJS service that facilitates communication with
the remote HTTP servers via the browser’s XMLHttpRequest object or via JSONP.
$http服务是AngularJs的核心服务,是通过浏览器的XMLHttpRequest对象或者JSONP来跟远程http服务
进行通信的.也就是说$http内部必然是通过封装的ajax来完成他的设计的。
$http是基于$q服务暴露出来的deferred/promise api,所以要知道$http的高级使用得熟悉这些api.
$http核心
1.扩展配置
2.把请求拦截器和响应拦截器放入promise链
3.把核心方法serverRequest放入promise链
核心方法里最终返回了promise对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47function $http(requestConfig) {
//忽略部分代码
//扩展了requestConfig
var config = extend({
method: 'get',
transformRequest: defaults.transformRequest,
transformResponse: defaults.transformResponse,
paramSerializer: defaults.paramSerializer
}, requestConfig);
config.headers = mergeHeaders(requestConfig);
config.method = uppercase(config.method);
config.paramSerializer = isString(config.paramSerializer) ?
$injector.get(config.paramSerializer) : config.paramSerializer;
//请求拦截器
var requestInterceptors = [];
//响应拦截器
var responseInterceptors = [];
//调用$q的静态方法when
var promise = $q.when(config);
// apply interceptors
//加入拦截器
forEach(reversedInterceptors, function(interceptor) {
if (interceptor.request || interceptor.requestError) {
//unshift在顶部插入
//unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
//随后在chain的时候一次取出两个元素
requestInterceptors.unshift(interceptor.request, interceptor.requestError);
}
if (interceptor.response || interceptor.responseError) {
//push在尾部插入
//push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
responseInterceptors.push(interceptor.response, interceptor.responseError);
}
});
promise = chainInterceptors(promise, requestInterceptors);
//核心请求放入promise链
promise = promise.then(serverRequest);
promise = chainInterceptors(promise, responseInterceptors);
//忽略部分代码
return promise;
}
serverRequest方法
serverRequest调用sendReq方法发送请求。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//放在promise里
function serverRequest(config) {
//配置的请求头
var headers = config.headers;
//转换请求数据
var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);
// strip content-type if data is undefined
if (isUndefined(reqData)) {
forEach(headers, function(value, header) {
if (lowercase(header) === 'content-type') {
delete headers[header];
}
});
}
if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
config.withCredentials = defaults.withCredentials;
}
//关键的步骤 发送请求
// send request
//返回新的promise供外部调用
return sendReq(config, reqData).then(transformResponse, transformResponse);
}
1 | function sendReq(config, reqData) { |