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 相关文章推荐
学习YUI.Ext第五日--做拖放Darg&Drop
Mar 10 Javascript
XHTML下,JS浮动代码失效的问题
Nov 12 Javascript
jquery应该如何来设置改变按钮input的onclick事件
Dec 10 Javascript
jquery 追加tr和删除tr示例代码
Sep 12 Javascript
Flexigrid在IE下不显示数据的有效处理方法
Sep 04 Javascript
JS实现Ajax的方法分析
Dec 20 Javascript
Angular客户端请求Rest服务跨域问题的解决方法
Sep 19 Javascript
详解node nvm进行node多版本管理
Oct 21 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
Nov 20 Javascript
Vue-cli3项目配置Vue.config.js实战记录
Jul 29 Javascript
基于Vue2-Calendar改进的日历组件(含中文使用说明)
Apr 14 Javascript
Vue中添加滚动事件设置的方法详解
Sep 14 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
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
PHP中Date获取时间不正确怎么办
2008/06/05 PHP
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
php使用json_encode对变量json编码
2014/04/07 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
JavaScript 使用技巧精萃(.net html
2009/04/25 Javascript
javascript时间函数基础介绍
2013/03/28 Javascript
js购物车实现思路及代码(个人感觉不错)
2013/12/23 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
JS实现文档加载完成后执行代码
2015/07/09 Javascript
js全选按钮的实现方法
2015/11/17 Javascript
浅析nodejs实现Websocket的数据接收与发送
2015/11/19 NodeJs
JS与jQ读取xml文件的方法
2015/12/08 Javascript
JavaScript实现DOM对象选择器
2016/09/24 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
2020/10/26 Javascript
JavaScript算法教程之sku(库存量单位)详解
2017/06/29 Javascript
javaScript手机号码校验工具类PhoneUtils详解
2017/12/08 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
Python实现基本数据结构中队列的操作方法示例
2017/12/04 Python
python实现m3u8格式转换为mp4视频格式
2018/02/28 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
2019/10/17 Python
css3 按钮样式简单可扩展创建
2013/03/18 HTML / CSS
自我评价怎么写好呢?
2013/12/05 职场文书
文明城市创建标语
2014/06/16 职场文书
竞选班长演讲稿400字
2014/08/22 职场文书
晋江市人民政府党组群众路线教育实践活动整改方案
2014/10/25 职场文书
群众路线教育实践活动学习笔记内容
2014/11/06 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
学生会副主席竞选稿
2015/11/19 职场文书
解除合同协议书范本
2016/03/21 职场文书
Oracle表空间与权限的深入讲解
2021/11/17 Oracle
配置nginx负载均衡
2022/05/06 Servers
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers