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 相关文章推荐
javascript最常用与实用的创建类的代码
Aug 12 Javascript
使用requestAnimationFrame实现js动画性能好
Aug 06 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
Oct 23 Javascript
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
辨析JavaScript中的Undefined类型与null类型
May 26 Javascript
JavaScript必看小技巧(必看)
Jun 07 Javascript
老生常谈js动态添加事件--- 事件委托
Jul 19 Javascript
微信小程序 条件渲染详解
Oct 09 Javascript
Jquery AJAX POST与GET之间的区别详细介绍
Oct 17 Javascript
Vue框架之goods组件开发详解
Jan 25 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
Jul 10 Javascript
详解react组件通讯方式(多种)
May 06 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 checkbox 取值详细说明
2010/08/19 PHP
详解WordPress中用于合成数组的wp_parse_args()函数
2015/12/18 PHP
PHP实现的超长文本分页显示功能示例
2018/06/04 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
js中的setInterval和setTimeout使用实例
2014/05/09 Javascript
AngularJS入门教程之学习环境搭建
2014/12/06 Javascript
jQuery构造函数init参数分析
2015/05/13 Javascript
JavaScript中反正弦函数Math.asin()的使用简介
2015/06/14 Javascript
JS模拟实现Select效果代码
2015/09/24 Javascript
基于javascript实现动态显示当前系统时间
2016/01/28 Javascript
Bootstrap被封装的弹层
2016/07/20 Javascript
Vue中使用vee-validate表单验证的方法
2018/05/09 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
javascript canvas封装动态时钟
2020/09/30 Javascript
python sys模块sys.path使用方法示例
2013/12/04 Python
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
python实现上传下载文件功能
2020/11/19 Python
python绘制中国大陆人口热力图
2018/11/07 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
2019/05/18 Python
Python如何对齐字符串
2020/07/30 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
Java的接口和C++的虚类的相同和不同处
2014/03/27 面试题
Kingsoft金山公司C/C++笔试题
2016/05/10 面试题
现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset
2012/11/09 面试题
文史专业毕业生自荐信
2013/11/17 职场文书
实习生个人的自我评价
2013/12/08 职场文书
重点工程汇报材料
2014/08/27 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
实习指导老师意见
2015/06/04 职场文书
使用react+redux实现计数器功能及遇到问题
2021/06/02 Javascript
Feign调用全局异常处理解决方案
2021/06/24 Java/Android
eval(cmd)与eval($cmd)的区别与联系
2021/07/07 PHP
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android
阿里云日志过滤器配置日志服务
2022/04/09 Servers