zoukankan      html  css  js  c++  java
  • angular的异步处理$q的使用(promise)

    Angular中的promise:

    Promise是一种异步方式处理值的方法。代表了一个函数最 终可能的返回值或者抛出的异常

    在之前,通常都是使用闭包或者回调来响应非同步的有意义数据

    使用promise的目的是:获得功能组合和错误冒泡(error bubbling)能力的同时,保持 代码异步运行的能力。

    $q的api:

      defer():用来生成一个延迟对象 var defer =$q.defer();

      reject():参数接收错误消息,相当于在回调函数中抛出一个异常,然后在下一个then中调用错误的回调函数。

      all():参数接收为一个promise数组,返回一个新的单一promise对象,当这些promise对象对应defer对象全部解决这个单一promise对象才会解决,当这些promise对象中有一个被reject了,这个单一promise同样的被reject了

           when(): 接收第一个参数为一个任意值或者是一个promise对象,其他 3个同promise的then方法,返回值为一个promise对象。第一个参数若不是promise对象则直接运行success回调且消息为这个对象,若为promise那么返回的promise其实就是对这个promise类型的参数的一个包装而已,被传入的这个promise对应的defer发 送的消息,会被我们when函数返回的promise对象所接收到

    <script>
    var app=angular.module("myApp",[])
    .controller("myCtrl",["$scope","$q",function(s,$q){ var promise = $q.when(1, function(num) {//参数不是promise,直接执行success回调且消息为这个对象 console.log("s" + num); }, function() { console.log("e"); }); var defer1 = $q.defer(); var promise1 = defer1.promise; var promise2 = $q.when(promise1, function(num) { console.log("s" + num); }, function() { console.log("e"); }); defer1.reject(1); }]); </script>

    结果:e,s1

     Demo2:

    var defer = $q.defer();
    var promise = defer.promise;
    promise.then(function() {
           return $q.reject("success error");
    }, function() {
           return $q.reject("error error");
    }).then(function(info) {
           document.write("s:" + info + "<br/>");
    }, function(info) {
           document.write("e:" + info + "<br/>");
    });

    defer.reject(1);//结果:e:error error

    defer.resolve(1);//结果:e:success error

    解释:reject():参数接收错误消息,相当于在回调函数中抛出一个异常,然后在下一个then中调用错误的回调函数。

    demo2:

    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <meta charset=utf-8 />
    <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script>
    <title>JS Bin</title>
    </head>
    <body ng-controller="myCtrl">
      <script>
        var app=angular.module("myApp",[])
        .controller("myCtrl",["$scope","$q",function(s,$q){
                var defer1 = $q.defer();
                  var promise1 = defer1.promise;
                  promise1.then(function(num) {
                            console.log("success" + num);
           },
           function(num) {
                  console.log("error" + num);
           });
        var defer2 = $q.defer();
        var promise2 = defer2.promise;
          promise2.then(function(num) {
                  console.log("success" + num);
           },
           function(num) {
                  console.log("error" + num);
    
           });
          var promise3 = $q.all([promise1, promise2]);
                     promise3.then(function(num) {
                      console.log(num );
          }, function(num) {
                      console.log( num);
          });
    //方式1
           defer1.resolve(1);
           defer2.resolve(2);
    //方式2
     //defer1.reject(1);
        }]);
      </script>
    </body>
    </html>

    结果:success1,success2, [1,2] 

    使用内置的$q服务,deferred API中提供了 一些方法。

    (1)    创建一个deferred对象:var deferred = $q.defer();

    deferred对象暴露了三个方法,以及一个可以用于处理promise的promise属性

                deferred.resolve(value):执行deferred promise   ,

               deferred.resolve({name:’Ari’,username:’@auser’ });

                deferred.reject(reason):拒接的defferred promise

                          deferred.reject(“cant’t update user”);<===> deferred.resolve($q.reject("Can't update user"));        

        deferred.notify(value): 用promise的执行状态来进行响应

    给你一个demo自己去体会:

    angular.module('myApp', [])
           .factory('GithubService', [ '$q', '$http', function($q, $http) {
              var getPullRequests = function() {
             var deferred = $q.defer(); // 从Github获取打开的angularjs pull请求列表  
         $http.get('https://api.github.com/repos/angular/angular.js/pulls')
          .success(function(data){ deferred.resolve(data); })
          .error(function(reason){ deferred.reject(reason); })
           return deferred.promise;
     }
       return { // 返回工厂对象
        getPullRequests: getPullRequests
        };
    }]);
    

      

    promise对象可以通过defer.promise获取,下面是promise对象的api:

    如何创建一个promise:

     var promise = defer.promise;

      promise对象可以通过defer.promise获取,下面是promise对象的api:

    1,then(successFn, errFn, notifyFn)

        在promise被执行或者拒绝之前,notifyFn回调可能会被调用0到多次,以提供过程状态的 提示

        then()方法总是返回一个新的promise,可以通过successFn或者errFn这样的返回值执行或 者被拒绝。它也能通过notifyFn提供通知。

     .controller(“HomeController”,function($scope,GithubService){
       GithubService.makeMultipleRwquest(‘……’)
                      .then(function(result){
                      //处理结果             
        },
    function(err){
    //请求失败,处理
    },function(percentComplete){
                $scope.progress= percentComplete;});    
    });

    2, Catch(errFn): 可以用.catch(function(reason){})取代err回调:

      $http.get('/repos/angular/angular.js/pulls')

         .catch(function(reason) { deferred.reject(reason); });

    3, finally(callback)当我们需要释放 一个资源,或者是运行一些清理工作,不管promise是成功还是失败时,这个方法会很有用

           注:不能直接调用这个方法,因为finally是IE中JavaScript的一个保留字。

           promise['finally'](function() {});

    demo:

    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
    <meta charset=utf-8 />
     <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script>
    <title>JS Bin</title>
    </head>
    <body ng-controller="myCtrl">
      <script>
        var app=angular.module("myApp",[])
        .controller("myCtrl",["$scope","$q",function(s,$q){
             function f1(num) {
               document.write("success:" + (num++) + "<br/>");
               return num;
            }
            function f2(num) {
                   document.write("errror:" + (num++) + "<br/>");
                   return num;
            }
            var defer = $q.defer();
            var promise = defer.promise;
          //方式1
            // promise.then(f1,f2).then(f1,f2);
          // 方式2
            //promise.then(f1,f2);
            //promise.then(f1,f2);
         // 方式3
           promise.then(f1,f2).then(f1,f2);//结果  error:7     success:8
           // promise.catch(f2);
           // promise.finally(f2);
         //方式4
           //promise.finally(f2).then(f1,f2);
          defer.reject(7);
        }]);
      </script>
    </body>
    </html>

    结果分别是什么呢?

    提示:angular中的then的链式调用中如果defer发送的reject的那么 只有第一个promise是reject的回调,其他的都是resolve的回调

    4, all() , 这个all()方法,可以把多个primise的数组合并成一个。当所有的promise执行成功后,会执行后面的回调。回调中的参数,是每个promise执行的结果。

    当批量的执行某些方法时,就可以使用这个方法。

     var funcA = function(){
                    var def = $q.defer();
                    console.log("funcA");
                    //some code
                    return def.promise;
                }
    var funcB = function(){
                    var def = $q.defer();
                    console.log("funcA");
                    //some code
                    return def.promise;
                }
    $q.all([funcA(),funcB()])
                .then(function(result){
                    console.log(result);
                });
    

      

    参考链接:http://www.cnblogs.com/fliu/articles/5288531.html

                  http://blog.csdn.net/renfufei/article/details/19174015

        http://liubin.org/promises-book/#promises-overview

        https://www.jianshu.com/p/5dc90b5e62c2

  • 相关阅读:
    对于GetBuffer() 与 ReleaseBuffer() 的一些分析
    _tmain与main,winMain,wmain收藏
    【引用】常用字符串长度计算函数
    Invalid URI
    Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI10" for linked server "DB1".
    Penang Industrial Zone
    Create Raid 1 and Raid 10 in one server
    Time zone BOGUS not found in registry
    'xxx_Forms' is not a valid Application Database or User 'sa' does not have sufficient permissions to check
    Syteline Goods Receiving Note Report
  • 原文地址:https://www.cnblogs.com/evaling/p/6732106.html
Copyright © 2011-2022 走看看