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 相关文章推荐
同一个表单 根据要求递交到不同页面的实现方法小结
Aug 05 Javascript
JavaScript 滚轮事件使用说明
Mar 07 Javascript
filters.revealTrans.Transition使用方法小结
Aug 19 Javascript
详解javascript遍历方式
Nov 11 Javascript
javascript中tostring()和valueof()的用法及两者的区别
Nov 16 Javascript
Angular 路由route实例代码
Jul 12 Javascript
JavaScript实现各种排序的代码详解
Aug 28 Javascript
Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能
Jan 26 Javascript
Vue底层实现原理总结
Feb 17 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
Aug 09 Javascript
微信小程序视图控件与bindtap之间的问题的解决
Apr 08 Javascript
Vue $attrs &amp; inheritAttr实现button禁用效果案例
Dec 07 Vue.js
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排序算法之基数排序(Radix Sort)实例详解
2018/04/21 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
Yii-自定义删除确认弹框(zyd)jquery实现代码
2013/03/04 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
JavaScript中的普通函数与构造函数比较
2015/04/07 Javascript
jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
2015/04/30 Javascript
jquery分析文本里url或邮件地址为真实链接的方法
2015/06/20 Javascript
bootstrap datepicker限定可选时间范围实现方法
2016/09/28 Javascript
微信小程序 弹框和模态框实现代码
2017/03/10 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
详解Node项目部署到云服务器上
2017/07/12 Javascript
vue2导航根据路由传值,而改变导航内容的实例
2017/11/10 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
阿望教你用vue写扫雷小游戏
2020/01/20 Javascript
VUE使用axios调用后台API接口的方法
2020/08/03 Javascript
vue 动态组件(component :is) 和 dom元素限制(is)用法说明
2020/09/04 Javascript
[03:27]《辉夜杯》线下训练营 导师CU和海涛指点迷津
2015/10/23 DOTA
[01:33]PWL开团时刻DAY2-开雾与反开雾
2020/10/31 DOTA
Python的Tornado框架异步编程入门实例
2015/04/24 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
树莓派采用socket方式文件传输(python)
2019/06/22 Python
jupyter notebook 的工作空间设置操作
2020/04/20 Python
Feelunique美国:欧洲大型的在线美妆零售电商
2018/11/04 全球购物
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
欧洲最大的预定车位市场:JustPark
2020/01/06 全球购物
SHEIN美国:购买时髦的女性服装
2020/12/02 全球购物
十一个高级MySql面试题
2014/10/06 面试题
个人求职信范文分享
2014/01/31 职场文书
中文专业学生自我评价范文
2014/02/06 职场文书
小学毕业感言50字
2014/02/16 职场文书
服装设计师求职信
2014/06/04 职场文书
2019通用版劳动合同范本!
2019/07/11 职场文书
2019年关于小学生课外阅读情况的分析报告
2019/12/02 职场文书
mysql中数据库覆盖导入的几种方式总结
2022/03/25 MySQL
Python如何利用pandas读取csv数据并绘图
2022/07/07 Python