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 学习之旅 (2)
Feb 05 Javascript
公共js在页面底部加载的注意事项介绍
Jul 18 Javascript
js中的eventType事件及其浏览器支持性介绍
Nov 29 Javascript
jquery获取元素索引值index()示例
Feb 13 Javascript
sails框架的学习指南
Dec 22 Javascript
JQuery异步获取返回值中文乱码的解决方法
Jan 29 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
Jun 06 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
Nov 03 Javascript
对vux点击事件的优化详解
Aug 28 Javascript
vue3.0 搭建项目总结(详细步骤)
May 20 Javascript
Vue与React的区别和优势对比
Dec 18 Vue.js
原生微信小程序开发中 redux 的使用详解
Feb 18 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
用Apache反向代理设置对外的WWW和文件服务器
2006/10/09 PHP
PHP 模板高级篇总结
2006/12/21 PHP
不错的一篇面向对象的PHP开发模式(简写版)
2007/03/15 PHP
PHP XML数据解析代码
2010/05/26 PHP
PHP页面转UTF-8中文编码乱码的解决办法
2015/10/20 PHP
PHP查看SSL证书信息的方法
2016/09/22 PHP
PHP常用日期加减计算方法实例小结
2018/07/31 PHP
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
2011/04/27 Javascript
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
浅谈jQuery this和$(this)的区别及获取$(this)子元素对象的方法
2016/11/29 Javascript
基于nodejs实现微信支付功能
2017/12/20 NodeJs
node下使用UglifyJS压缩合并JS文件的方法
2018/03/07 Javascript
ng-alain表单使用方式详解
2018/07/10 Javascript
详解Vue组件插槽的使用以及调用组件内的方法
2018/11/13 Javascript
vue双向绑定及观察者模式详解
2019/03/19 Javascript
jQuery删除/清空指定元素的所有子节点实例代码
2019/07/04 jQuery
微信小程序如何获取地址
2019/12/24 Javascript
JS实现图片懒加载(lazyload)过程详解
2020/04/02 Javascript
原生JavaScript实现轮播图
2021/01/10 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
[17:45]DOTA2 HEROES教学视频教你分分钟做大人-军团指挥官
2014/06/11 DOTA
[05:41]2014DOTA2西雅图国际邀请赛 小组赛7月10日TOPPLAY
2014/07/10 DOTA
Python实现批量转换文件编码的方法
2015/07/28 Python
详解Python发送email的三种方式
2018/10/18 Python
详解Python 正则表达式模块
2018/11/05 Python
python中强大的format函数实例详解
2018/12/05 Python
python爬虫筛选工作实例讲解
2020/11/23 Python
python程序实现BTC(比特币)挖矿的完整代码
2021/01/20 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
MYSQL基础面试题
2012/05/13 面试题
PyQt 如何创建自定义QWidget
2021/03/24 Python
双语教学实施方案
2014/03/23 职场文书
敬老院院长事迹材料
2014/05/21 职场文书
法定授权委托证明书
2014/09/27 职场文书
离职信范文
2015/06/23 职场文书