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版代码高亮
Jun 26 Javascript
在视频前插入广告
Nov 20 Javascript
javascript 中的console.log和弹出窗口alert
Aug 30 Javascript
JS中对数组元素进行增删改移的方法总结
Dec 15 Javascript
浅谈JavaScript的计时器对象
Dec 26 Javascript
JavaScript与JQUERY获取元素的宽、高和位置
Feb 26 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
Nov 13 Javascript
vue组件实践之可搜索下拉框功能
Nov 25 Javascript
解决Vue调用springboot接口403跨域问题
Sep 02 Javascript
Layui table field初始化加载时进行隐藏的方法
Sep 19 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
Jul 12 Javascript
jQuery实现简单评论区功能
Oct 26 jQuery
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
2006/12/14 PHP
php读取html并截取字符串的简单代码
2009/11/30 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)
2015/09/22 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
如何让页面加载完成后执行js
2013/06/26 Javascript
JS 获取滚动条高度示例代码
2013/10/24 Javascript
Chrome扩展页面动态绑定JS事件提示错误
2014/02/11 Javascript
使用js操作css实现js改变背景图片示例
2014/03/10 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
2014/05/10 Javascript
js对象基础实例分析
2015/01/13 Javascript
基于jquery实现无限级树形菜单
2016/03/22 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
基于input动态模糊查询的实现方法
2017/12/12 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
JS实现区分中英文并统计字符个数的方法示例
2018/06/09 Javascript
vue实现与安卓、IOS交互的方法
2018/11/02 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
Vue响应式原理Observer、Dep、Watcher理解
2019/06/06 Javascript
vue实现数字滚动效果
2020/06/29 Javascript
swiper自定义分页器的样式
2020/09/14 Javascript
使用BeautifulSoup爬虫程序获取百度搜索结果的标题和url示例
2014/01/19 Python
Python入门篇之正则表达式
2014/10/20 Python
TensorFlow Session使用的两种方法小结
2018/07/30 Python
Python本地及虚拟解释器配置过程解析
2020/10/13 Python
婚前财产公证书
2014/04/10 职场文书
世界遗产的导游词
2015/02/13 职场文书
2015年大学生工作总结
2015/04/21 职场文书
农业项目投资意向书
2015/05/09 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
2015年乡镇安全生产工作总结
2015/05/19 职场文书
民政局2016年“六一”儿童节慰问活动总结
2016/04/06 职场文书
2019年教师节祝福语精选,给老师送上真诚的祝福
2019/09/09 职场文书
Python机器学习应用之基于线性判别模型的分类篇详解
2022/01/18 Python
Python 绘制多因子柱状图
2022/05/11 Python