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 相关文章推荐
使用jQuery UI的tooltip函数修饰title属性的气泡悬浮框
Jun 24 Javascript
eclipse导入jquery包后报错的解决方法
Feb 17 Javascript
jQuery 插件开发指南
Nov 14 Javascript
JS代码实现百度地图 画圆 删除标注
Oct 12 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单
Nov 25 Javascript
AngularJS过滤器filter用法分析
Dec 11 Javascript
详解Javascript中DOM的范围
Feb 13 Javascript
vue实现todolist单页面应用
Apr 11 Javascript
JavaScript实现简单的文本逐字打印效果示例
Apr 12 Javascript
在vue项目中引入highcharts图表的方法
Jan 21 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
Sep 03 Javascript
在vue中使用eslint,配合vscode的操作
Nov 09 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 按指定元素值去除数组元素的实现方法
2011/11/04 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
2016/05/18 PHP
PHP从零开始打造自己的MVC框架之类的自动加载实现方法详解
2019/06/03 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
9个JavaScript评级/投票插件
2010/01/18 Javascript
Javascript 判断Flash是否加载完成的代码
2010/04/12 Javascript
javascript各浏览器中option元素的表现差异
2011/04/07 Javascript
js移除事件 js绑定事件实例应用
2012/11/28 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
jquery使用$(element).is()来判断获取的tagName
2014/08/24 Javascript
教你用javascript实现随机标签云效果_附代码
2016/03/16 Javascript
标准的js无缝滚动效果
2016/08/30 Javascript
AngularJS Select(选择框)使用详解
2017/01/18 Javascript
webpack学习--webpack经典7分钟入门教程
2017/06/28 Javascript
使用react-router4.0实现重定向和404功能的方法
2017/08/28 Javascript
bootstrap select下拉搜索插件使用方法详解
2017/11/23 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
[53:20]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 VG vs OG
2018/04/03 DOTA
[43:24]VG vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
Python中使用md5sum检查目录中相同文件代码分享
2015/02/02 Python
Python基于tkinter模块实现的改名小工具示例
2017/07/27 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
PyQt4实时显示文本内容GUI的示例
2019/06/14 Python
Python字典对象实现原理详解
2019/07/01 Python
基于OpenCV的路面质量检测的实现
2020/11/04 Python
Python中lru_cache的使用和实现详解
2021/01/25 Python
CSS3区域模块region相关编写示例
2015/08/28 HTML / CSS
HTML5 实现图片上传预处理功能
2020/02/06 HTML / CSS
威尔逊皮革:Wilsons Leather
2018/12/07 全球购物
Sperry澳大利亚官网:源自美国帆船鞋创始品牌
2019/07/29 全球购物
担保书怎么写
2014/04/01 职场文书
高中运动会广播稿
2014/09/16 职场文书
大学生军训感言
2015/08/01 职场文书
幼儿园小班班务总结
2015/08/03 职场文书