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 相关文章推荐
让iframe自适应高度(支持XHTML,支持FF)
Jul 24 Javascript
JavaScript高级程序设计(第3版)学习笔记8 js函数(中)
Oct 11 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
Jan 21 Javascript
获得Javascript对象属性个数的示例代码
Nov 21 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
javascript删除一个html元素节点的方法
Dec 20 Javascript
HTML5 实现的一个俄罗斯方块实例代码
Sep 19 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
Feb 18 Javascript
微信小程序实现的日期午别医生排班表功能示例
Jan 09 Javascript
浅谈JavaScript中等号、双等号、 三等号的区别
Aug 06 Javascript
React服务端渲染原理解析与实践
Mar 04 Javascript
React四级菜单的实现
Apr 08 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版(4)
2006/10/09 PHP
php生成EXCEL的东东
2006/10/09 PHP
Google 静态地图API实现代码
2010/11/19 Javascript
从零开始学习jQuery (三) 管理jQuery包装集
2011/02/23 Javascript
Javascript变量函数浅析
2011/09/02 Javascript
jquery图片放大镜功能的实例代码
2013/03/26 Javascript
Javascript的时间戳和php的时间戳转换注意事项
2013/04/12 Javascript
jQuery之折叠面板的深入解析
2013/06/19 Javascript
js猜数字小游戏的简单实现代码
2013/07/02 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
2014/05/14 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】
2016/05/10 Javascript
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
jQueryUI Datepicker组件设置日期高亮
2016/10/13 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
JS实现的简单分页功能示例
2018/08/23 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
2018/09/13 Javascript
layui实现tab的添加拒绝重复的方法
2019/09/04 Javascript
ckeditor一键排版功能实现方法分析
2020/02/06 Javascript
[02:44]重置世界,颠覆未来——DOTA2 7.23版本震撼上线
2019/12/01 DOTA
Python中正则表达式详解
2017/05/17 Python
pandas 取出表中一列数据所有的值并转换为array类型的方法
2018/04/11 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
2019/07/24 Python
keras:model.compile损失函数的用法
2020/07/01 Python
详解css3中的伪类before和after常见用法
2020/11/17 HTML / CSS
如何查找网页漏洞
2016/06/22 面试题
教师实习期自我鉴定
2013/10/06 职场文书
考博自荐信
2013/10/25 职场文书
《陶罐和铁罐》教学反思
2014/02/19 职场文书
车间主任岗位职责范本
2015/04/08 职场文书
2015年财政所工作总结
2015/04/25 职场文书
婚礼伴郎致辞
2015/07/28 职场文书
聊一聊python常用的编程模块
2021/05/14 Python
自动在Windows中运行Python脚本并定时触发功能实现
2021/09/04 Python
mysql 获取时间方式
2022/03/20 MySQL