angularjs的异步处理机制
2018-01-04 17:25
155 查看
JS的常规请求方式是同步的,这样容易造成阻塞,而后来改进引入了ajax来处理异步请求,同样是对XMLHTTPRequest的封装,angularjs也提供了异步处理机制。怎样理解异步请求呢?
现在寒冬将至,我需要一套被子,以度过寒冬。于是我向被服店发起一个请求,那就是替我定制一套被服。当然定制的话需要一定的时间来生产,我并不着急,放下定金我就走了,并告诉店主,做好了给我送过去,并留下地址和联系方式。那么我就可以去做其他的事情,我不可能因为这点事情而耽误生活继续。这就是简单的我发起了一个异步请求,也可以称为可延期的请求。但是我不会无限期的等待,所以我需要跟店主确认需要多长时间来处理这个事情,显然我不可能等过整个寒冬,那这个被子对我来说将毫无意义。所以我需要店主的一个承诺,一个promise。店主将承诺时间告诉我这就叫做$q.defer延期请求,并可以通过某种回执来时刻关注进展情况。这种就叫做deferred,延期事件。
在这个请求的过程中,我们可以想到有很多的情况,比如,由于机器损坏或者被子的原料不够,需要从外地进货,不能按期完成,那么在处理这个请求的过程中,店主就可以发起reject回执,从而来减少我的等待,你做不了,我就需要得到一个回执,然后我需要找其他的店铺来处理这种事情。当然这种reject不单单包含回执消息还可以包含其他的东西,你比如定金回退,违约金回退,以及原因等消息。如果这个请求事件一直进行的比较顺利,店家又比较贴心,那么他会实时或者每天,每周给我发个消息,来汇报被子的进展情况,这就叫通知notify。最后,店家如期的将被子做好,送到我住的地方,我给他个好评,整个请求的过程完满结束,那就是处理完成了,我们称为resolve。
从上面我们可以看到,一次异步请求应当包含但不仅包含这三个方面。看一下如何来使用这种异步方式。
看起来跟ajax的很相似,那么他本身是个什么东西呢?我们来打印一下:
可以看到输出结果如下,它包含了成功success,失败error的回调函数,并且包含了header,状态码,以及一些请求的数据,这也就是一个promise对象。
来看一下,这几个方法有什么不同的地方:
我们看一下打印结果,从这里面我们可以明显看出,success中的数据就是我们想要的服务端返回的数据,而在then中我们发现他不但包含了我们的服务端的数据,还包含状态码以及header部分,当然由于状态码是200,说明这次请求是成功了,所以不会打印error中的东西:
从上面可以看出来,我们通过$q创建的deferred对象中就包含一个promise,promise中的方法和属性跟$http返回的一致。可以看出多出来的就是,notify(通知),reject(拒绝),resolve(解决),这三个回调函数,我们在success中会使用deferred.resolve来处理返回的数据,而在error中使用deferred.reject来处理数据。处理之后将返回一个promise对象,不管成功失败。
那么promise提供的方法promise.then(successFunc,errorFunction,notifyFunc),来处理异步不同的结果。
successFunc将会在resolve执行之后被调用。
errorFunc将会在reject之后被调用。
notifyFunc将会在notify之后被调用。
catch回调负责处理其他的异常处理。
finally回调负责释放资源或者刷新操作等。
$q创建promise有两种方式。
controller中:
看一下执行结果:
换一种写法:
输出结果:
我们来看看另外一种创建方式:
service中:
controller中:
所以一张被子可能不足以御寒,那么我就需要再去店里定制另一张被子,当然我也许会多订一些比如被罩,枕巾
之类的东西,那我我就会在请求一次,那么我陆陆续续的下了好多订单,我不会去选择记住每一个的请求和时间,
我会采取一次性制作完成再统一给我送过来,这样我就不需要去关注某一个了。angualrjs的$q也支持这种操作
它可以将你的多个promise都在all里面处理。也就是说$q.all可以接受一个数组的形式。当所有的promise都resolve
,它会将他们都存到自己的resolve中,然后统一返回。当然如果有一个出现reject的时候,他也会把reject存到自己
的reject中,但只会有一个,不会出现多个的形式。
输出结果:
在上面,我定义了四个promise,其中有两个是reject的,那么我们来看看输出结果是怎么样的呢?
哎呦,就输出一个。由此可以看出,只要是有一个reject的,那么就只会输出一个reject结果,不管你其他的
promise是否执行resolve的,而且多个reject的是不会叠加的,只会输出第一个reject。
现在寒冬将至,我需要一套被子,以度过寒冬。于是我向被服店发起一个请求,那就是替我定制一套被服。当然定制的话需要一定的时间来生产,我并不着急,放下定金我就走了,并告诉店主,做好了给我送过去,并留下地址和联系方式。那么我就可以去做其他的事情,我不可能因为这点事情而耽误生活继续。这就是简单的我发起了一个异步请求,也可以称为可延期的请求。但是我不会无限期的等待,所以我需要跟店主确认需要多长时间来处理这个事情,显然我不可能等过整个寒冬,那这个被子对我来说将毫无意义。所以我需要店主的一个承诺,一个promise。店主将承诺时间告诉我这就叫做$q.defer延期请求,并可以通过某种回执来时刻关注进展情况。这种就叫做deferred,延期事件。
在这个请求的过程中,我们可以想到有很多的情况,比如,由于机器损坏或者被子的原料不够,需要从外地进货,不能按期完成,那么在处理这个请求的过程中,店主就可以发起reject回执,从而来减少我的等待,你做不了,我就需要得到一个回执,然后我需要找其他的店铺来处理这种事情。当然这种reject不单单包含回执消息还可以包含其他的东西,你比如定金回退,违约金回退,以及原因等消息。如果这个请求事件一直进行的比较顺利,店家又比较贴心,那么他会实时或者每天,每周给我发个消息,来汇报被子的进展情况,这就叫通知notify。最后,店家如期的将被子做好,送到我住的地方,我给他个好评,整个请求的过程完满结束,那就是处理完成了,我们称为resolve。
从上面我们可以看到,一次异步请求应当包含但不仅包含这三个方面。看一下如何来使用这种异步方式。
1.$http
在谈及$q之前,先来了解一下$http。$http是angularjs封装的http应用,用于同服务器请求,类似于ajax的一种封装,我们来看看它的形式,当然既然是angularjs提供的,那么我们需要首先引入$http这种服务,才能正常的使用。$http({ method:'GET', url:'api/ham/guest/account/getAccountList' });
看起来跟ajax的很相似,那么他本身是个什么东西呢?我们来打印一下:
var promise = $http({ method:'GET', url:'api/ham/guest/account/getAccountList' });
console.log("promise",promise);
可以看到输出结果如下,它包含了成功success,失败error的回调函数,并且包含了header,状态码,以及一些请求的数据,这也就是一个promise对象。
来看一下,这几个方法有什么不同的地方:
var promise = $http({ method:'GET', url:'api/ham/guest/account/getAccountList' });
promise.success(function (data) {
console.log("data",data);
});
promise.then(function (data) {
console.log("success",data)
});
promise.error(function (data) {
console.log("error",data)
})
我们看一下打印结果,从这里面我们可以明显看出,success中的数据就是我们想要的服务端返回的数据,而在then中我们发现他不但包含了我们的服务端的数据,还包含状态码以及header部分,当然由于状态码是200,说明这次请求是成功了,所以不会打印error中的东西:
2.$q
$q是angularjs封装的一种promise的实现,通过$q来创建promise。其实在上面的例子中我们就知道了一个promise的内容,那么由$q来创建的promise有什么不同呢?function getList() { var deferred = $q.defer(); console.log("deferred",deferred); $http.get(ovHttp.proxy('api/ham/guest/account/getAccountList')) .success(function (data, status) { //if (data.result == 'success') { deferred.resolve(data); //} //else if (data.result != 'success') { // //handleError(); //} }); console.log("deferred.promise",deferred.promise); return deferred.promise; }
从上面可以看出来,我们通过$q创建的deferred对象中就包含一个promise,promise中的方法和属性跟$http返回的一致。可以看出多出来的就是,notify(通知),reject(拒绝),resolve(解决),这三个回调函数,我们在success中会使用deferred.resolve来处理返回的数据,而在error中使用deferred.reject来处理数据。处理之后将返回一个promise对象,不管成功失败。
那么promise提供的方法promise.then(successFunc,errorFunction,notifyFunc),来处理异步不同的结果。
successFunc将会在resolve执行之后被调用。
errorFunc将会在reject之后被调用。
notifyFunc将会在notify之后被调用。
catch回调负责处理其他的异常处理。
finally回调负责释放资源或者刷新操作等。
$q创建promise有两种方式。
2.1 第一种方式
service中:function testQ(){ return $q(function (resolve, reject) { $timeout(function () { if(1==1){ resolve("resolve"); }else{ reject("reject"); } },1000) }) }
controller中:
amGuestAccountService.testQ().then( function (data) { console.log("success",data); }, function (data) { console.log("error",data); }) .catch(function (data) { console.log("error",data); });
看一下执行结果:
换一种写法:
function testQ(){ return $q(function (resolve, reject) { $timeout(function () { if(1!=1){ resolve("resolve"); }else{ reject("reject"); } },1000) }) }
输出结果:
2.2 第二种方式
我们来看看另外一种创建方式:service中:
function getList() { var deferred = $q.defer(); console.log("deferred",deferred); $http.get(ovHttp.proxy('api/ham/guest/account/getAccountList')) .success(function (data, status) { deferred.resolve(data); }, function (data,status) { deferred.reject("reject the request"); }); return deferred.promise; }
controller中:
amGuestAccountService.getList().then(function (data) { console.log("resolve",data); }, function (data) { console.log("reject",data) }, function (data) { console.log("notify",data); });
2.3 promise的其他方法
在处理这种异步操作的时候,有时我们会碰到这种需求。我可能觉得北京今年的天气特别冷,比以往都要冷,所以一张被子可能不足以御寒,那么我就需要再去店里定制另一张被子,当然我也许会多订一些比如被罩,枕巾
之类的东西,那我我就会在请求一次,那么我陆陆续续的下了好多订单,我不会去选择记住每一个的请求和时间,
我会采取一次性制作完成再统一给我送过来,这样我就不需要去关注某一个了。angualrjs的$q也支持这种操作
它可以将你的多个promise都在all里面处理。也就是说$q.all可以接受一个数组的形式。当所有的promise都resolve
,它会将他们都存到自己的resolve中,然后统一返回。当然如果有一个出现reject的时候,他也会把reject存到自己
的reject中,但只会有一个,不会出现多个的形式。
function q1() { var deferred = $q.defer(); $timeout(function () { deferred.notify("1 notify"); if (1==1) { deferred.resolve("1 resolved"); } else { deferred.reject("1 reject"); } }, 1000); return deferred.promise; } function q2() { var deferred = $q.defer(); $timeout(function () { deferred.notify("2 notify"); if (1==1) { deferred.resolve("2 resolved"); } else { deferred.reject("2 reject"); } }, 1000); return deferred.promise; }
$q.all([q1(),q2()]).then(function (data) { console.log("resolve",data); }, function (data) { console.log("reject",data) }, function (data) { console.log("notify",data); });
输出结果:
function q1() { var deferred = $q.defer(); $timeout(function () { deferred.notify("1 notify"); if (1==1) { deferred.resolve("1 resolved"); } else { deferred.reject("1 reject"); } }, 1000); return deferred.promise; } function q2() { var deferred = $q.defer(); $timeout(function () { deferred.notify("2 notify"); if (1!=1) { deferred.resolve("2 resolved"); } else { deferred.reject("2 reject"); } }, 1000); return deferred.promise; } function q3() { var deferred = $q.defer(); $timeout(function () { deferred.notify("3 notify"); if (1!=1) { deferred.resolve("3 resolved"); } else { deferred.reject("3 reject"); } }, 1000); return deferred.promise; } function q4() { var deferred = $q.defer(); $timeout(function () { deferred.notify("4 notify"); if (1==1) { deferred.resolve("4 resolved"); } else { deferred.reject("4 reject"); } }, 1000); return deferred.promise; }
在上面,我定义了四个promise,其中有两个是reject的,那么我们来看看输出结果是怎么样的呢?
哎呦,就输出一个。由此可以看出,只要是有一个reject的,那么就只会输出一个reject结果,不管你其他的
promise是否执行resolve的,而且多个reject的是不会叠加的,只会输出第一个reject。
相关文章推荐
- AngularJS 百科笔记
- angularJs中的form指令的使用
- 使用angularJs实现tab切换
- 给angularJs的service建模
- AngularJS学习记录-过滤器(匹配方式过滤)
- 【转载】图灵AngularJS入门教程
- [转载]AngularJS入门教程02:AngularJS模板
- AngularJS(2)——AngularJS数据双向绑定
- 深究AngularJS中$sce的使用
- Unknown provider: formatFileSizeFilterProvider <- formatFileSizeFilter AngularJS
- angularjs三级联动
- Angularjs 双重循环获取父级下标$index
- AngularJS学习(二)——Angular应用的解析
- AngularJs分页插件
- angularjs的config和interceptor - session注入
- AngularJS中ng-include随屏幕宽度改变实例
- AngularJs获取数组的元素例子
- angularJS - directive
- 【AngularJS】AngularJS 教程
- 【AngularJS】学习笔记