angularjs中$q详解

异步编程模式的一种模式,但是不是很明白他跟JQuery的deferred对象有什么区别。随着公司项目的进行,要跟后台接数据了,所以决定搞定它;我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的话必须牺牲控制流、异常处理和函数语义化为代价,甚至会让我们掉进出现callback大坑,而promise解决了这个问题。

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

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

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

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


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>异步编程模式</title>
    <script type="text/javascript" src="../angular-1.4.0-rc.2/angular.js"></script>
    <script>
        angular.module('myApp', [])
                .controller('firstController', ['$scope', '$q', '$timeout', function ($scope, $q, $timeout) {

                    $scope.okToGreet = function (name) {
                        return name === 'Robin Hood';
                    }
                    $scope.asyncGreet = function (name) {
                        var deferred = $q.defer();
                        $timeout(function () {
                        // 因为这个异步函数fn在未来的异步执行,我们把代码包装到 $apply 调用中,一边正确的观察到 model 的改变
                            $scope.$apply(function(){
                                deferred.notify('About to greet'+name+'.');
                                if($scope.okToGreet(name)){
                                    console.log('aaaa');
                                    deferred.resolve('Hello,'+name+'!');
                                }else{
                                    deferred.reject('Greet'+name+'is not allowed.');
                                }
                            });

                        }, 1000);
                        return deferred.promise;
                    }
                    var promise  = $scope.asyncGreet('Robin Hood1');
                    promise.then(function(greeting){
                        alert('Success: ' + greeting);
                    },function(reason){
                        alert('Failed: ' + reason);
                    },function(update){
                        alert('Got notification: ' + update);
                    });
                }]);


    </script>
</head>
<body ng-app="myApp" ng-controller="firstController">

</body>
</html>

Q Promise的基本用法


上面代码表示, $q.defer() 构建的 deffered 实例的几个方法的作用。如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);

如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。最后返回 deferred.promise ,我们就可以链式调用then方法。

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 任务完成时,允许感兴趣的部分取得其执行结果。

romise 对象的方法

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 被拒绝还是解决。

$q的其他方法

$q.when(value):传递变量值,promise.then()执行成功回调

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


所谓的Promise是神马?

ECMAScript 是 JavaScript 语言的国际标准,JavaScript 是 ECMAScript 的实现。ES6 的目标,是使得 JavaScript 语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。

概念

ES6 原生提供了 Promise 对象。

所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

Promise 对象有以下两个特点。

(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。


(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。












  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值