1. 程式人生 > >AngularJS $q 和 $q.all 單個數據源和多個數據源合並(promise的說明)

AngularJS $q 和 $q.all 單個數據源和多個數據源合並(promise的說明)

獲取 lar debug let index 被拒 可用 第一個 brush

這篇文章講的不錯, 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!

AngularJS $q 和 $q.all 單個數據源和多個數據源合並(promise的說明)