Angular中的Promise对象($q介绍)


Posted in Javascript onMarch 03, 2015

在用JQuery的时候就知道 promise 是 Js异步编程模式的一种模式,但是不是很明白他跟JQuery的deferred对象有什么区别。随着公司项目的进行,要跟后台接数据了,所以决定搞定它。

Promise

Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件。

我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的话必须牺牲控制流、异常处理和函数语义化为代价,甚至会让我们掉进出现callback大坑,而promise解决了这个问题。

ES6中Promise、angularJS内置的AngularJS内置Q,以及when采用的都是Promises/A规范,如下:

每个任务都有三种状态:未完成(pending)、完成(fulfilled)、失败(rejected)。

1.pending状态:可以过渡到履行或拒绝状态。
2.fulfilled状态:不能变为其他任何状态,而且状态不能改变,必须有value值。
3.rejected状态:不能变为其他任何状态,而且状态不能改变,必须有reason。

状态的转移是一次性的,状态一旦变成fulfilled(已完成)或者failed(失败/拒绝),就不能再变了。

function okToGreet(name){

    return name === 'Robin Hood';

}

 

function asyncGreet(name) {

    var deferred = $q.defer();

 

    setTimeout(function() {

     // 因为这个异步函数fn在未来的异步执行,我们把代码包装到 $apply 调用中,一边正确的观察到 model 的改变

        $scope.$apply(function() {

            deferred.notify('About to greet ' + name + '.');

 

            if (okToGreet(name)) {

                deferred.resolve('Hello, ' + name + '!');

            } else {

                deferred.reject('Greeting ' + name + ' is not allowed.');

            }

        });

    }, 1000);

 

    return deferred.promise;

}

 

var promise = asyncGreet('Robin Hood');

promise.then(function(greeting) {

    alert('Success: ' + greeting);

}, function(reason) {

    alert('Failed: ' + reason);

}, function(update) {

    alert('Got notification: ' + update);

});

Q Promise的基本用法

上面代码表示, $q.defer() 构建的 deffered 实例的几个方法的作用。如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。最后返回 deferred.promise ,我们就可以链式调用then方法。

JS将要有原生Promise,ES6中已经有Promise对象,firefox和Chrome 32 beta版本已经实现了基本的Promise API

AngularJs中的$q.defferd

通过 调用 $q.defferd 返回deffered对象以链式调用。该对象将Promises/A规范中的三个任务状态通过API关联。

deffered API

deffered 对象的方法

1.resolve(value):在声明resolve()处,表明promise对象由pending状态转变为resolve。
2.reject(reason):在声明resolve()处,表明promise对象由pending状态转变为rejected。
3.notify(value) :在声明notify()处,表明promise对象unfulfilled状态,在resolve或reject之前可以被多次调用。

deffered 对象属性

promise :最后返回的是一个新的deferred对象 promise 属性,而不是原来的deferred对象。这个新的Promise对象只能观察原来Promise对象的状态,而无法修改deferred对象的内在状态可以防止任务状态被外部修改。

Promise API

当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过 deferred.promise 得到该引用。

promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。

promise 对象的方法

1.then(errorHandler, fulfilledHandler, progressHandler):then方法用来监听一个Promise的不同状态。errorHandler监听failed状态,fulfilledHandler监听fulfilled状态,progressHandler监听unfulfilled(未完成)状态。此外,notify 回调可能被调用 0到多次,提供一个进度指示在解决或拒绝(resolve和rejected)之前。
2.catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
3.finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。 更多的信息请参阅 完整文档规范.

通过then()方法可以实现promise链式调用。

promiseB = promiseA.then(function(result) {  

  return result + 1;  

});  

 

// promiseB 将会在处理完 promiseA 之后立刻被处理,  

// 并且其  value值是promiseA的结果增加1

$q的其他方法

$q.when(value):传递变量值,promise.then()执行成功回调
$q.all(promises):多个promise必须执行成功,才能执行成功回调,传递值为数组或哈希值,数组中每个值为与Index对应的promise对象

Javascript 相关文章推荐
实现png图片和png背景透明(支持多浏览器)的方法
Sep 08 Javascript
在Node.js应用中使用Redis的方法简介
Jun 24 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
May 27 Javascript
JS正则子匹配实例分析
Dec 22 Javascript
canvas实现图像放大镜
Feb 06 Javascript
Vue.js之slot深度复制详解
Mar 10 Javascript
vue学习笔记之指令v-text && v-html && v-bind详解
May 12 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
Jan 17 Javascript
Vue用v-for给src属性赋值的方法
Mar 03 Javascript
解决LayUI表单获取不到data的问题
Aug 20 Javascript
浅谈微信页面入口文件被缓存解决方案
Sep 29 Javascript
基于vue+element实现全局loading过程详解
Jul 10 Javascript
Javascript设计模式之观察者模式的多个实现版本实例
Mar 03 #Javascript
Node.js 学习笔记之简介、安装及配置
Mar 03 #Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
Mar 03 #Javascript
JavaScript跨浏览器获取页面中相同class节点的方法
Mar 03 #Javascript
JS实现鼠标点击展开或隐藏表格行的方法
Mar 03 #Javascript
浅谈JavaScript数据类型
Mar 03 #Javascript
JavaScript中property和attribute的区别详细介绍
Mar 03 #Javascript
You might like
ajax+php打造进度条代码[readyState各状态说明]
2010/04/12 PHP
PHP生成随机用户名和密码的实现代码
2013/02/27 PHP
浅析PHP的ASCII码转换类
2013/07/05 PHP
PHP函数eval()介绍和使用示例
2014/08/20 PHP
php实现获取及设置用户访问页面语言类
2014/09/24 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
Yii实现单用户博客系统文章详情页插入评论表单的方法
2015/12/28 PHP
Jquery getJSON方法详细分析
2013/12/26 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
2016/06/08 Javascript
BooStrap对导航条的改造实践小结
2016/09/21 Javascript
浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法
2017/02/06 Javascript
javascript过滤数组重复元素的实现方法
2017/05/03 Javascript
React Native 集成jpush-react-native的示例代码
2017/08/16 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
js技巧之十几行的代码实现vue.watch代码
2018/06/09 Javascript
微信小程序开发之tabbar图标和颜色的实现
2018/10/17 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
2020/07/20 Javascript
[05:42]DOTA2英雄梦之声_第10期_蝙蝠骑士
2014/06/21 DOTA
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
用Python实现一个简单的线程池
2015/04/07 Python
Python生成随机数组的方法小结
2017/04/15 Python
python中的tcp示例详解
2018/12/09 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
HTML5制作表格样式
2016/11/15 HTML / CSS
Hotels.com爱尔兰:全球酒店预订
2017/02/24 全球购物
香港交友网站:be2香港
2018/07/22 全球购物
激光脱毛、蓝光和护肤:Tria Beauty
2019/03/28 全球购物
个人求职信范例
2014/01/29 职场文书
毕业生就业推荐表自我鉴定
2014/03/20 职场文书
小学生九一八纪念日83周年演讲稿500字
2014/09/17 职场文书
普通党员四风问题对照检查材料
2014/09/27 职场文书
2015秋季开学典礼主持词
2015/07/16 职场文书
开学典礼致辞
2015/07/29 职场文书
教师旷工检讨书
2015/08/15 职场文书
《领导干部从政道德启示录》学习心得体会
2016/01/20 职场文书
Nginx location 和 proxy_pass路径配置问题小结
2021/09/04 Servers