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 相关文章推荐
日期 时间js控件
May 07 Javascript
JQuery中如何传递参数如click(),change()等具体实现
Apr 28 Javascript
JS去除数组重复值的五种不同方法
Sep 06 Javascript
原生JS实现加入收藏夹的代码
Oct 24 Javascript
TinyMCE提交AjaxForm获取不到数据的解决方法
Mar 05 Javascript
jQuery手动点击实现图片轮播特效
Apr 20 Javascript
javascript动态获取登录时间和在线时长
Feb 25 Javascript
jQuery UI结合Ajax创建可定制的Web界面
Jun 22 Javascript
jQuery实现简单倒计时功能的方法
Jul 04 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
关于meta viewport中target-densitydpi属性详解(推荐)
Aug 18 Javascript
Vue自定义指令结合阿里云OSS优化图片的实现方法
Nov 12 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
ExtJS与PHP、MySQL实现存储的方法
2010/04/02 PHP
去除链接虚线全面分析总结
2006/08/15 Javascript
js调用css属性写法
2013/09/21 Javascript
jQuery中操控hidden、disable等无值属性的方法
2014/01/06 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
全面解析标签页的切换方式
2016/08/21 Javascript
JS实现颜色梯度与渐变效果完整实例
2016/12/30 Javascript
JavaScript实现瀑布流图片效果
2017/06/30 Javascript
js点击时关闭该范围下拉菜单之外的菜单方法
2018/01/11 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
微信小程序页面渲染实现方法
2019/11/06 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
nodejs制作小爬虫功能示例
2020/02/24 NodeJs
Python获取网页上图片下载地址的方法
2015/03/11 Python
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
Python基于pygame模块播放MP3的方法示例
2017/09/30 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
Python爬虫实现(伪)球迷速成
2018/06/10 Python
提升Python效率之使用循环机制代替递归函数
2019/07/23 Python
python实现知乎高颜值图片爬取
2019/08/12 Python
python防止随意修改类属性的实现方法
2019/08/21 Python
python命令 -u参数用法解析
2019/10/24 Python
python如何爬取网页中的文字
2020/07/28 Python
python Zmail模块简介与使用示例
2020/12/19 Python
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
网络艺术零售业的先驱者:artrepublic
2017/09/26 全球购物
Otticanet意大利:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/03/10 全球购物
入党自我鉴定
2014/03/25 职场文书
合作投资意向书
2014/04/01 职场文书
我们的节日清明节活动总结
2014/04/30 职场文书
会计出纳岗位职责
2015/03/31 职场文书
2015年推普周活动方案
2015/05/06 职场文书
检举信的写法
2019/04/10 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
Python爬虫数据的分类及json数据使用小结
2021/03/29 Python