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!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM