AngularJS 中的Promise --- $q服务详解


Posted in Javascript onSeptember 14, 2016

先说说什么是Promise,什么是$q吧。Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered。

什么是Promise

以前了解过Ajax的都能体会到回调的痛苦,同步的代码很容易调试,但是异步回调的代码,会让开发者陷入泥潭,无法跟踪,比如:

funA(arg1,arg2,function(){
  funcB(arg1,arg2,function(){
    funcC(arg1,arg2,function(){
       xxxx....
    })
  })  
})

本身嵌套就已经很不容易理解了,加上不知何时才触发回调,这就相当于雪上加霜了。

但是有了Promise这种规范,它能帮助开发者用同步的方式,编写异步的代码,比如在AngularJS中可以使用这种方式:

deferABC.resolve(xxx)
.then(funcSuccess(){},funcError(){},funcNotify(){});

当resolve内的对象成功执行,就会触发funcSuccess,如果失败就会触发funcError。有点类似

deferABC.resolve(function(){
  Sunccess:funcSuccess,
  error:funcError,
  notify:funcNotify
})

再说的直白点,Promise就是一种对执行结果不确定的一种预先定义,如果成功,就xxxx;如果失败,就xxxx,就像事先给出了一些承诺。

比如,小白在上学时很懒,平时总让舍友带饭,并且事先跟他说好了,如果有韭菜鸡蛋就买这个菜,否则就买西红柿炒鸡蛋;无论买到买不到都要记得带包烟。

小白让舍友带饭()
.then(韭菜鸡蛋,西红柿炒鸡蛋)
.finally(带包烟)

$q服务

q服务是AngularJS中自己封装实现的一种Promise实现,相对与Kris Kwal's Q要轻量级的多。
先介绍一下$q常用的几个方法:

defer() 创建一个deferred对象,这个对象可以执行几个常用的方法,比如resolve,reject,notify等
all() 传入Promise的数组,批量执行,返回一个promise对象
when() 传入一个不确定的参数,如果符合Promise标准,就返回一个promise对象。

在Promise中,定义了三种状态:等待状态,完成状态,拒绝状态。

关于状态有几个规定:

1 状态的变更是不可逆的
2 等待状态可以变成完成或者拒绝

defer()方法

在$q中,可以使用resolve方法,变成完成状态;使用reject方法,变成拒绝状态。

下面看看 $q的简单使用:

<html ng-app="myApp">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body>
  <div ng-controller="myctrl">
    {{test}}
  </div>
  <script type="text/javascript">
     var myAppModule = angular.module("myApp",[]);
     myAppModule.controller("myctrl",["$scope","$q",function($scope, $ q ){
      $scope.test = 1;//这个只是用来测试angularjs是否正常的,没其他的作用

      var defer1 = $q.defer();
      var promise1 = defer1.promise;

      promise1
      .then(function(value){
        console.log("in promise1 ---- success");
        console.log(value);
      },function(value){
        console.log("in promise1 ---- error");
        console.log(value);
      },function(value){
        console.log("in promise1 ---- notify");
        console.log(value);
      })
      .catch(function(e){
        console.log("in promise1 ---- catch");
        console.log(e);
      })
      .finally(function(value){
        console.log('in promise1 ---- finally');
        console.log(value);
      });

      defer1.resolve("hello");
      // defer1.reject("sorry,reject");
     }]);
  </script>
</body>
</html>

其中defer()用于创建一个deferred对象,defer.promise用于返回一个promise对象,来定义then方法。then中有三个参数,分别是成功回调、失败回调、状态变更回调。

其中resolve中传入的变量或者函数返回结果,会当作第一个then方法的参数。then方法会返回一个promise对象,因此可以写成

xxxx
.then(a,b,c)
.then(a,b,c)
.then(a,b,c)
.catch()
.finally()

继续说说上面那段代码,then...catch...finally可以想想成java里面的try...catch...finally。

all()方法

这个all()方法,可以把多个primise的数组合并成一个。当所有的promise执行成功后,会执行后面的回调。回调中的参数,是每个promise执行的结果。

当批量的执行某些方法时,就可以使用这个方法。

var funcA = function(){
        console.log("funcA");
        return "hello,funA";
      }
      var funcB = function(){
        console.log("funcB");
        return "hello,funB";
      }
      $q.all([funcA(),funcB()])
      .then(function(result){
        console.log(result);
      });

执行的结果:

funcA
funcB
Array [ "hello,funA", "hello,funB" ]

when()方法

when方法中可以传入一个参数,这个参数可能是一个值,可能是一个符合promise标准的外部对象。     

var funcA = function(){
        console.log("funcA");
        return "hello,funA";
      }
      $q.when(funcA())
      .then(function(result){
        console.log(result);
      });

当传入的参数不确定时,可以使用这个方法。

hello,funA

以上就是对AngularJS 中的Promise --- $q服务的资料详细介绍,后续继续补充相关资料,谢谢大家对本站的支持!

Javascript 相关文章推荐
删除重复数据的算法
Nov 23 Javascript
用prototype实现的简单小巧的多级联动菜单
Mar 24 Javascript
HTML代码中标签的全部属性 中文注释说明
Mar 26 Javascript
兼容IE/Firefox/Opera/Safari的检测页面装载完毕的脚本Ext.onReady的实现
Jul 14 Javascript
跟着Jquery API学Jquery之一 选择器
Apr 07 Javascript
JavaScript获取当前网页标题(title)的方法
Apr 03 Javascript
JS时间特效最常用的三款
Aug 19 Javascript
jQuery实现响应鼠标事件的图片透明效果【附demo源码下载】
Jun 16 Javascript
js实现开启密码大写提示
Dec 21 Javascript
JS动画定时器知识总结
Mar 23 Javascript
微信小程序swiper实现滑动放大缩小效果
Nov 15 Javascript
koa2的中间件功能及应用示例
Mar 05 Javascript
AngularJS bootstrap启动详解及实例代码
Sep 14 #Javascript
AngularJS equal比较对象实例详解
Sep 14 #Javascript
AngularJS API之copy深拷贝详解及实例
Sep 14 #Javascript
AngularJS $injector 依赖注入详解
Sep 14 #Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
Sep 14 #Javascript
详解XMLHttpRequest(一)同步请求和异步请求
Sep 14 #Javascript
AngularJs ng-route路由详解及实例代码
Sep 14 #Javascript
You might like
十天学会php(1)
2006/10/09 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
PHP魔术方法使用方法汇总
2016/02/14 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
用js模拟JQuery的show与hide动画函数代码
2010/09/20 Javascript
js各种验证文本框输入格式(正则表达式)
2010/10/22 Javascript
关于JS数组追加数组采用push.apply的问题
2014/06/09 Javascript
JavaScript判断是否为数组的3种方法及效率比较
2015/04/01 Javascript
javascript随机显示背景图片的方法
2015/06/18 Javascript
Bootstrap每天必学之前端开发框架
2015/11/19 Javascript
jQuery中事件与动画的总结分享
2016/05/24 Javascript
JS生成和下载二维码的代码
2016/12/07 Javascript
20行JS代码实现粘贴板复制功能
2018/02/06 Javascript
vue项目中添加单元测试的方法
2018/07/21 Javascript
Angularjs之ngModel中的值验证绑定方法
2018/09/13 Javascript
Vue filter 过滤器、以及在table中的使用介绍
2020/09/07 Javascript
[46:43]DOTA2上海特级锦标赛D组小组赛#1 EG VS COL第三局
2016/02/28 DOTA
[54:06]OG vs TNC 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python进程间通信用法实例
2015/06/04 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
如何使用Python实现自动化水军评论
2019/06/26 Python
Python爬虫使用代理IP的实现
2019/10/27 Python
python实现简单颜色识别程序
2020/02/19 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
Tkinter中复选菜单是否被选中的判断与设置方式
2020/03/04 Python
keras的ImageDataGenerator和flow()的用法说明
2020/07/03 Python
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
德国咖啡批发商:Coffeefair
2019/08/26 全球购物
BSTN意大利:德国街头和运动文化高品质商店
2020/12/22 全球购物
给物业的表扬信
2014/01/21 职场文书
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
药剂专业毕业生求职信
2014/06/24 职场文书
中小学生学籍证明
2014/10/25 职场文书
2015年毕业实习工作总结
2014/12/12 职场文书
学校国庆节活动总结
2015/03/23 职场文书
撤诉申请书法院范本
2015/05/18 职场文书