2013-07-26 96 views
78

我知道通常只有在使用承諾時纔會附加具有then()調用和連鎖行爲的繼續代碼。

不過,我想揭開序幕承諾包裹的異步調用,然後分別揭開序幕3秒$timeout()這樣我就可以採取UI操作,僅在最初的承諾尚未完成。 (我預計這隻會發生在連接速度較慢,3G上的移動設備等)

給出承諾,我可以檢查它是否完整或沒有阻塞或等待?

+2

我的角度對這個打開的問題,並得到了有益的響應https://github.com/angular/angular.js/issues/8307#issuecomment-49903373 – derekdreery

+0

的可能重複http://stackoverflow.com/questions/27039771/q-js-is-it-it-know-if-a-promise-has-resolved-rejected-or-not – mvermand

回答

36

我認爲你最好的選擇是,(不修改角源和提交拉請求)是保持一個本地標誌,如果承諾已被解決。每當您設置您感興趣的承諾時重置它,並將原始承諾的then()標記爲完整。在$timeoutthen()檢查標誌以瞭解原始承諾是否已解決。

事情是這樣的:

var promiseCompleted = false; 
promise.then(function(){promiseCompleted=true;}) 
$timeout(...).then(function(){if(!promiseCompleted)doStuff()}) 

克里斯·科瓦爾的實現包括其他方法來檢查承諾的狀態,但它似乎角的實施$q遺憾的是不包括這些。

+7

這裏最好使用.finally()。 上面提供的代碼只會在promiseCompleted標誌成功解析的情況下標記爲true。 –

+0

好點,最後可能會更好 – shaunhusain

0

我不知道你的確切情況,但是在進行異步調用(並生成承諾)之後立即將超時放在適當位置更爲典型。

提供setTimeout()語句與異步調用在同一事件線程中,您不必擔心競爭效果的可能性。由於JavaScript嚴格是單線程的,承諾的.then()回調被保證在稍後的事件線程中觸發。

+0

然後,當瀏覽器開始實現象'node'這樣的異步javascript時,你的代碼就會中斷。 –

8

這似乎不可能,因爲@shaunhusain已經提到過。但也許這是沒有必要:

// shows stuff from 3s ahead to promise completetion, 
// or does and undoes it in one step if promise completes before 
$q.all(promise, $timeout(doStuff, 3000)).then(undoStuff); 

或可能更好:

var tooSlow = $timeout(doStuff, 3000); 
promise.always(tooSlow.cancel); 
1

我也有過類似的問題,我需要檢查,如果一個承諾又回來了。由於AngularJS的$watch函數將在呈現頁面時註冊一個更改,即使新值和舊值都未定義,我也必須檢查是否有值存儲在我的外部模型中的任何數據。

這絕對是一個黑客,但我這樣做:

$scope.$watch('userSelection', function() { 
    if(promiseObject.hasOwnProperty("$$v"){ 
    userExportableState.selection = $scope.userSelection; 
    } 
}; 

我知道$$v是AngularJS使用的內部變量,但它已經相當可靠的,對我們來說是解決了承諾的指標。誰知道當我們升級到AngularJS 1.2時會發生什麼: - /我沒有看到在1.2文檔中提到$q的改進,但也許有人會寫一個更接近Q的更好功能的替代服務。

+0

謝謝,但比使用「私人」成員有更好的選擇。 – Jackson

45

我想這是在最近的版本中添加角但現在似乎是對承諾的$$狀態對象:

var deferred = $q.defer(); 
console.log(deferred.promise.$$state.status); // 0 
deferred.resolve(); 
console.log(deferred.promise.$$state.status); //1 

如不建議這樣做,因爲它可能打破評論中指出升級你的Angular版本時。

+23

Angular docs表示不應該使用$$ ...屬性。升級到更新版本的Angular時可能會有風險... – hgoebl

+7

太糟糕Angular在銀盤上提供它的私有變量。 :( – Jackson

+2

另請參閱:http://stackoverflow.com/questions/27039771/q-js-is-it-possible-to-know-if-a-promise-has-resolved-rejected-or-not – mvermand