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

在用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对象

(0)

相关推荐

  • 详解Angular.js的$q.defer()服务异步处理

    首先本文以个人目前项目的部分代码为例说明为什么要用deferred. function getBase64(img){//传入图片路径,返回base64 function getBase64Image(img,width,height) { var canvas = document.createElement("canvas"); canvas.width = width ? width : img.width; canvas.height = height ? height : i

  • angularjs 处理多个异步请求方法汇总

    在实际业务中经常需要等待几个请求完成后再进行下一步操作.但angularjs中$http不支持同步的请求. 解决方法一: 复制代码 代码如下: $http.get('url1').success(function (d1) {         $http.get('url2').success(function (d2) {             //处理逻辑         });     }); 解决方法二: then中的方法会按顺序执行. 复制代码 代码如下: var app = ang

  • AngularJS中的Promise详细介绍及实例代码

    Angular中的Promise 在用jQuery的时候就知道 promise 是 Js异步编程模式的一种模式,但是不是很明白他跟JQuery的deferred对象有什么区别.随着公司项目的进行,要跟后台接数据了,所以决定搞定它. Promise Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件. 我们知道,在编写JavaScript异步代码时,callback是最最简单的机制,可是用这种机制的话必须牺牲控制流.异常处理和函数语义化为代价,甚至会

  • 浅谈Angular的$q, defer, promise

    1. $q $q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常). 2. defer defer的字面意思是延迟,$q.defer() 可以创建一个deferred实例(延迟对象实例). deferred 实例旨在暴露派生的Promise 实例,以及被用来作为成功完成或未成功完成的信号API,以及当前任务的状态.这听起来好复杂的样子,总结$q, defer, promise三者之间的关系如下所示. var deferred = $q

  • AngularJS中的promise用法分析

    本文实例讲述了AngularJS中的promise用法.分享给大家供大家参考,具体如下: JavaScript异步回调有好处也有坏处,回调函数大量嵌套十分复杂.所以javascript中还有另一种异步处理模式叫promises.在AngularJS中的实现就是$q服务. 下面是一些小例子. then,catch,finally 在链最后的 catch 为整个链式处理提供一个异常处理点 在链最后的 finally 总是会被执行,不管 promise 被处理或者被拒绝,起清理作用 <!DOCTYPE

  • AngularJS中update两次出现$promise属性无法识别的解决方法

    前言 本文主要介绍的是在AngularJS中update两次出现$promise属性无法识别的解决方法,下面话不多说,先来看看错误提示,然后再看看解决的办法吧. 一.错误信息如下: ERROR 2015-12-02 14:33:17,653 http-bio-8080-exec-42 o.s.s.r.i.e.InternalErrorExceptionMapper - Unrecognized field "$promise" (class com.inetpsa.fnd.rest.c

  • AngularJS 中的Promise --- $q服务详解

    先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过Ajax的都能体会到回调的痛苦,同步的代码很容易调试,但是异步回调的代码,会让开发者陷入泥潭,无法跟踪,比如: funA(arg1,arg2,function(){ funcB(arg1,arg2,function(){ funcC(arg1,arg2,function(){ xxxx.... })

  • AngularJS 实现按需异步加载实例代码

    AngularJS 通过路由支持多视图应用, 可以根据路由动态加载所需的视图, 在 AngularJS 的文档中有详细的介绍, 网上也有不少教程, 就不用介绍了! 随着视图的不断增加,js文件会越来越多,而 AngularJS 默认需要把全部的js都一次性加载,使用起来非常不便, 因此按需加载模块的需求会越来越强,不过,AngularJS 并没有实现按需加载. 习惯了 seajs 的异步加载方式,也想着 angular 也能同样使用异步加载,但是事实不随人愿. angularjs 和 requi

  • AngularJS中处理多个promise的方式

    在使用AngularJS中处理promise的时候,有时会碰到需要处理多个promise的情况. 最简单的处理就是每个promise都then.如下: var app = angular.module("app",[]); app.controller("AppCtrl", function($q. $timeout){ var one = $q.defer(); var two = $q.defer(); var three = $q.defer(); $time

  • AngularJS出现$http异步后台无法获取请求参数问题的解决方法

    本文实例讲述了AngularJS出现$http异步后台无法获取请求参数问题的解决方法.分享给大家供大家参考,具体如下: angular在通过异步提交数据时使用了与jQuery不一样的请求头部和数据序列化方式,导致部分后台程序无法正常解析数据. 原理分析(网上的分析): 对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用.发起请求.读取响应.检查状态码,最后处理服务端的响应.整个过程示例如下: var xmlht

  • 详解Javacript和AngularJS中的Promises

    比如页面调用google地图的api时就使用到了promise. function success(position){ var cords = position.coords; console.log(coords.latitude + coords.longitude); } function error(err){ console.warn(err.code+err.message) } navigator.geolocation.getCurrentPosition(success, e

  • 浅析Angular2子模块以及异步加载

    用Angular2开发一个大型的应用,我们通常都需要分模块进行开发.例如将某一个功能的相关页面和功能放在一个模块里面,这样既可以实现系统的松耦合,给开发和后期的维护带来很大的便利.同时,对于子模块,我们还可以使用延时加载,这样可以减少初始加载的文件的大小.在这篇文章中,我们就来看看在Angular2框架下怎么实现子模块及其延时加载. 可以在这里查看本文使用的实例.该实例基于上篇文章Angular2使用Guard和Resolve进行验证和权限控制 所用的实例,并在它基础上添加了一个lazy的模块,

随机推荐