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 日期处理之时区问题
Oct 08 Javascript
jQuery中:reset选择器用法实例
Jan 04 Javascript
基于d3.js实现实时刷新的折线图
Aug 03 Javascript
js判断请求的url是否可访问,支持跨域判断的实现方法
Sep 17 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
Dec 30 Javascript
简单理解Vue中的nextTick方法
Jan 30 Javascript
WebSocket的通信过程与实现方法详解
Apr 29 Javascript
JavaScript实现多态和继承的封装操作示例
Aug 20 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
Aug 29 Javascript
p5.js实现简单货车运动动画
Oct 23 Javascript
ES6学习笔记之let与const用法实例分析
Jan 22 Javascript
Vue中 axios delete请求参数操作
Aug 25 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
索趣科技的答案
2007/02/07 Javascript
(JS实现)MapBar中坐标的加密和解密的脚本
2007/05/16 Javascript
通过Javascript创建一个选择文件的对话框代码
2012/06/16 Javascript
javascript面向对象入门基础详细介绍
2012/09/05 Javascript
用js实现trim()的解决办法
2013/04/16 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
js同源策略详解
2015/05/21 Javascript
如何使用jquery easyui创建标签组件
2015/11/18 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
2016/03/01 Javascript
JS动态插入并立即执行回调函数的方法
2016/04/21 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
JS控制HTML元素的显示和隐藏的两种方法
2016/09/27 Javascript
Vue2.x中的Render函数详解
2017/05/30 Javascript
深入研究jQuery图片懒加载 lazyload.js使用方法
2017/08/16 jQuery
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
jquery使用FormData实现异步上传文件
2018/10/25 jQuery
vue计算属性computed的使用方法示例
2019/03/13 Javascript
vue2配置scss的方法步骤
2019/06/06 Javascript
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
微信跳一跳游戏python脚本
2020/04/01 Python
Python常见工厂函数用法示例
2018/03/21 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
python pandas修改列属性的方法详解
2018/06/09 Python
如何优雅地处理Django中的favicon.ico图标详解
2018/07/05 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
python调用函数、类和文件操作简单实例总结
2019/11/29 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
2020/03/11 Python
html5 Canvas画图教程(11)—使用lineTo/arc/bezierCurveTo画椭圆形
2013/01/09 HTML / CSS
Expedia挪威官网:酒店、机票和租车
2018/03/03 全球购物
全球最大运动品牌的男装、女装和童装官方库存商:A&A Sports
2021/01/17 全球购物
查摆问题自我剖析材料
2014/08/18 职场文书
转让协议书范本
2014/09/13 职场文书
新员工试用期自我评价
2015/03/10 职场文书
mybatis 解决从列名到属性名的自动映射失败问题
2021/06/30 Java/Android
Java反应式框架Reactor中的Mono和Flux
2021/07/25 Java/Android