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 checkbox 全选/反选及批量删除
Apr 28 Javascript
jQuery Tools Dateinput使用介绍
Jul 14 Javascript
JavaScript起点(严格模式深度了解)
Jan 28 Javascript
Javascript 浮点运算的问题分析与解决方法
Aug 27 Javascript
JQuery伸缩导航练习示例
Nov 13 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
Jan 09 Javascript
jQuery原型属性和原型方法详解
Jul 07 Javascript
浅谈jQuery中setInterval()方法
Jul 07 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
May 09 Javascript
使用D3.js制作图表详解
Aug 13 Javascript
vue父组件点击触发子组件事件的实例讲解
Feb 08 Javascript
记录一次完整的react hooks实践
Mar 11 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 前加at符合@的作用解析
2015/07/31 PHP
详细解读PHP的Yii框架中登陆功能的实现
2015/08/21 PHP
在laravel5.2中实现点击用户头像更改头像的方法
2019/10/14 PHP
php将字符串转换为数组实例讲解
2020/05/05 PHP
一些常用的JS功能函数代码
2009/06/23 Javascript
精选的10款用于构建良好易用性网站的jQuery插件
2011/01/23 Javascript
《JavaScript高级程序设计》阅读笔记(二) ECMAScript中的原始类型
2012/02/27 Javascript
jquery查找父元素、子元素(个人经验总结)
2014/04/09 Javascript
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
详解JavaScript中的客户端消息框架设计原理
2015/06/24 Javascript
浅析Javascript中bind()方法的使用与实现
2016/05/30 Javascript
ES6所改良的javascript“缺陷”问题
2016/08/23 Javascript
JavaScript浮点数及运算精度调整详解
2016/10/21 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
canvas学习之API整理笔记(二)
2016/12/29 Javascript
jQuery鼠标悬停内容动画切换效果
2017/04/27 jQuery
仿淘宝JSsearch搜索下拉深度用法
2018/01/15 Javascript
vue watch监听对象及对应值的变化详解
2018/02/24 Javascript
Vue登录注册并保持登录状态的方法
2018/08/17 Javascript
javascript定时器的简单应用示例【控制方块移动】
2019/06/17 Javascript
[59:59]EG vs IG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Windows下PyMongo下载及安装教程
2015/04/27 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
python字符串替换re.sub()实例解析
2020/02/09 Python
解决TensorFlow程序无限制占用GPU的方法
2020/06/30 Python
详解Pandas 处理缺失值指令大全
2020/07/30 Python
python 爬取免费简历模板网站的示例
2020/09/27 Python
html5手机键盘弹出收起的处理
2020/01/20 HTML / CSS
Hotels.com日本:国外和海外住宿,酒店预订
2019/12/13 全球购物
毕业生毕业总结的自我评价范文
2013/11/02 职场文书
cf搞笑广告词
2014/03/14 职场文书
实习介绍信模板
2015/01/30 职场文书
2016企业先进集体事迹材料
2016/02/25 职场文书
vue使用wavesurfer.js解决音频可视化播放问题
2022/04/04 Vue.js
Python matplotlib绘制雷达图
2022/04/13 Python