zoukankan      html  css  js  c++  java
  • AngularJS $q 和 $q.all 单个数据源和多个数据源合并(promise的说明)

    这篇文章讲的不错, angular $q  和 promise!!

    --------------------------------------------------------------

    通过调用  $q.defer() 可以构建一个新的 deffered 实例。
    deffered 对象用来将 Promise 实例与 标记任务状态(执行成功还是不成功)的 API 相关联。

    deffered 对象的方法

    • resolve(value) ——传入 value 解决派生的 promise。 如果 value 是一个通过 $q.reject 构造的拒绝对象(rejection) , 该promise 将被拒绝。
    • reject(reason) ——拒绝派生的promise,并提供原因 。 这相当于通过 $q.reject构造的拒绝对象(rejection)作为参数传递给 resolve。
    • notify(value)  ——在 promise 执行的过程中提供状态更新。 这在 promise 被解决或拒绝之前可能会被多次调用。

    deffered 对象的属性

    promise – {Promise} —— 与延迟(deferred)相关联的 promise 对象。

    承诺 接口 | Promise API

    当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过  deferred.promise 得到该引用。
    promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。

    promise 对象的方法

    • then(successCallback, errorCallback, notifyCallback) ——不管 promise 是被处理还是被拒绝, 一旦结果可用,then 就会尽快地异步调用 成功/错误 回调函数 只要结果是可用的。 调用回调函数时传递单个参数: 结果 或拒绝的理由。 此外,notify 回调可能被调用 0到多次,以提供 提供一个进度指示,之前承诺解决或拒绝。

               这个方法 返回一个新的promise 对象, 根据 successCallback , errorCallback的返回值进行解决或拒绝 。 它还通过 notifyCallback 方法的返回值进行通知。 promise 不能从notifyCallback方法得到解决或拒绝 。

    • catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
    • finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。 更多的信息

                因为在 ES3版本的JavaScript中 finally 是一个保留字关键字,不能作为属性名,为了适配 IE8,您需要使用  promise['finally'](callback) 这种形式来调用该方法。

    研究了一下$q回调服务,看来半天都是似懂非懂的样子,感觉实现了异步加载的功能,还是动手试验并记录下来,如果不对欢迎指正(后台是ASP.Net Web API模拟的)

    第一种情况的回调,对单个数据源的请求

    myApp.factory('myService', function ($http, $q) {  
                return {  
                    getAllData: function () {  
                        //定义一个回调服务  
                        var deferred = $q.defer();  
                        $http.get('/API/Values')//此时获取的是单个数据源  
                            .success(function (result) {  
                                //将结果委托回调函数  
                                deferred.resolve(result);  
                            })  
                            .error(function (result) {  
                                debugger;  
                            });  
                        //返回回调函数结果  
                        return deferred.promise;  
                    }  
                };  
            });  
      function FetchCtrl($scope, $http, $templateCache, myService, myServiceAll) {  
                  
                $scope.fetch = function () {  
                     
                    var result = myService.getAllData();  
                    //通过回调函数结果得到数据值  
                    result.then(function (data) {  
                        $scope.result = data;  
                };  
      
            }  
    }

    第二种情况的回调,对多个数据源的请求,最后同时将多个结果集合并一起返回

    //服务声明  
            myApp.factory('myServiceAll', function ($http, $q) {  
                return {  
                    getAllData: function () {  
                        //定义一个回调服务  
                        var deferred = $q.defer();  
                        //定义两个获取的源路径  
                        var p1 = $http.get('/API/Values');  
                        var p2 = $http.get('/API/Values/0');  
                        $q.all([p1, p2])  
                        .then(function (results) {  
                            var aggregatedData = [];  
                            angular.forEach(results, function (result) {  
                                aggregatedData = aggregatedData.concat(result.data);  
                            });  
                            //将结果委托回调函数  
                            deferred.resolve(aggregatedData);  
                        });  
                        //返回回调函数结果  
                        return deferred.promise;  
                    }  
                }  
            });  
       
     function FetchCtrl($scope, $http, $templateCache, myService, myServiceAll) {  
                  
                $scope.fetch = function () {  
                //通过回调函数结果得到数据值  
                    var result = myServiceAll.getAllData();  
                    result.then(function (data) {  
      
                        $scope.result = data;  
                    })  
                };  
      
            }  

    方法简介

    $q service 四个方法函数 , 按照个人理解划分为三类。

    1. 非链式调用

      $q.when(value)

      传递变量值,promise.then()执行成功回调

      $q.all(promises)

      多个promise必须执行成功,才能执行成功回调,传递值为数组或哈希值,数组中每个值为与Index对应的promise对象。

    2. 错误信息传递

      $q.reject(reason)

      返回一个失败原因,promise.then()执行失败回调

    3. 链式调用

      $q.defer()

      返回一个deferred对象

    • resolve(value) – 简化说明 配置该deferred对象promise的成功调用函数参数
    • reject(reason) – 简化说明 配置该deferred对象promise的失败调用函数参数
    • promise - 简化说明 配置后的promise对象

    个人理解说明

    链式调用内部的默认失败回调会向后传递异常,所以为避免麻烦,且不在意每一处的业务逻辑错误,不要在每一处then()处声明异常处理函数,在最后一个 then()中声明即可。

          promiseX.then(function(){}).then(function(){})
    .then(function(val){},function(reason){})

    如果在意每一处可能出现的业务逻辑错误,在回调中return $q.reject();传递错误.无论执行哪一个回调函数,如果内部没有人为return $q.reject();,则若没有执行错误,暨返回成功信号。

    var deferred = $q.defer();
    deferred.resolve(1);
    var promiseA = deferred.promise;
    promiseA
    .then(function(val){$log.info(val);return ++val;})
    .then(function(val){$log.info(val);return ++val;})
    .then(
    function(val){$log.info(val);return ++val;},
    function(val){$log.info(val)}
    );

    链式调用完成后控制台打印出 1,2,3

    var deferred = $q.defer();
    deferred.resolve(1);
    var promiseA = deferred.promise;
    promiseA
    .then(function(val){$log.info(val);return $q.reject(15);})
    .then(function(val){$log.info(val);return ++val;})
    .then(function(val){$log.info(val);return ++val;})
    .then(function(val){$log.info(val);return ++val;})
    .then(
    function(val){$log.info(val);return ++val;},
    function(val){$log.info(val)}
    );

    链式调用完成后控制台打印出 1,15,可以看出,第一个return $q.reject(15)之后,直到最后一个then()才有错误回调函数,所以异常一直传递到最后,中间的几个then()没有错误回调函数。

     $q.when('I Love you!')
    .then(function(value){$log.info(value)});

    控制台打印出I Love you!;

     $q.when($q.reject('I Hate you!'))
    .then(null,function(value){$log.info(value)});

    控制台打印出I Hate you!;

     var promiseA = $q.when('I Love you!');
    var promiseB = $q.when('Love story!');
    var promiseC = $q.when("Let't get wet!");
    $q.all([promiseA,promiseB,promiseC]).then(function(value){
    value[0].then(function(value){$log.info(value);})
    value[1].then(function(value){$log.info(value);})
    value[2].then(function(value){$log.info(value);})
    })

    控制台打印出I Love you!,Love story!,"Let't get wet!

  • 相关阅读:
    [nodejs]npm国内npm安装nodejs modules终极解决方案
    [nodejs]解决mysql和连接池(pool)自动断开问题
    [nodejs]国内npm安装nodejs modules失败的几个解决方案
    [less]用webstorm自动编译less产出css和sourcemap
    [javascript] Promise API
    [javascript]巧用sourcemap快速定位javascript中的问题
    Gruntjs提高生产力(四)
    Gruntjs提高生产力(三)
    Gruntjs提高生产力(二)
    Gruntjs提高生产力(一)
  • 原文地址:https://www.cnblogs.com/oxspirt/p/7058923.html
Copyright © 2011-2022 走看看