Açısal bir $ q vaadinin Çözümlenip Çözülmediğini Kontrol Etme


84

Sözleri kullanırken tipik olarak bir then()çağrı ve zincirleme davranışı ile devam kodu ekleneceğini anlıyorum .

Ancak, $timeout()SADECE orijinal söz henüz tamamlanmadıysa, sözlerle sarmalanmış bir eşzamansız aramayı başlatmak ve ardından 3 saniyeyi ayrı olarak başlatmak istiyorum. (Bunun yalnızca yavaş bağlantılarda, 3G'de mobil cihazlarda vb. Olacağını tahmin ediyorum.)

Bir söz verildiğinde, engellemeden veya beklemeden tamamlanıp tamamlanmadığını kontrol edebilir miyim?


2
Bu konuda açısal olarak bir sorun açtım ve faydalı bir yanıt aldım github.com/angular/angular.js/issues/8307#issuecomment-49903373
derekdreery

Yanıtlar:


46

Sanırım bu, Angular'ın yeni bir sürümüne eklendi, ancak şu anda vaatte bir $$ durum nesnesi var gibi görünüyor:

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

Yorumlarda belirtildiği gibi, Angular sürümünüzü yükseltirken bozulabileceği için bu önerilmez.


25
Açısal dokümanlar, $$...özelliklerin kullanılmaması gerektiğini söylüyor .
Angular'ın

7
Çok kötü Angular, özel değişkenlerini gümüş tepside sunar. :(
Jackson


2
Ama ama ... Angular inspectişlevi uygulamadı . Yani bizim için meyve suyu yok Angular geliştiriciler. Promise prototipi buna sahip değil.
Robert Koritnik

36

Bence en iyi seçeneğiniz, (Açısal kaynağı değiştirmeden ve bir çekme talebi göndermeden) sözün çözülüp çözülmediği için yerel bir bayrak tutmaktır. İlgilendiğiniz sözü her belirlediğinizde sıfırlayın then()ve orijinal söz için tamamlandı olarak işaretleyin . Gelen $timeout then()orijinal vaat henüz ya da değil çözülmüş olup olmadığını kontrol bayrağı bilmek.

Bunun gibi bir şey:

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

Kris Kowal'ın uygulaması sözün durumunu kontrol etmek için başka yöntemler içerir, ancak Angular'ın uygulaması $qmaalesef bunları içermiyor.


9
Burada .finally () kullanmak daha iyi olur. Yukarıda sağlanan kod, promiseCompleted bayrağını yalnızca başarılı bir şekilde çözülmüşse doğru olarak işaretleyecektir.
Karanvir Kang

8

@Shaunhusain'in de bahsettiği gibi, bu mümkün görünmüyor. Ama belki gerekli değildir:

// 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);

veya belki daha iyi:

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

1

Bir sözün geri dönüp dönmediğini kontrol etmem gereken benzer bir sorun yaşadım. AngularJS'nin $watchişlevi, hem yeni hem de eski değerler tanımlanmamış olsa bile sayfayı işlerken bir değişiklik kaydedeceğinden, harici modelimde depolamaya değer herhangi bir veri olup olmadığını kontrol etmem gerekiyor.

Kesinlikle bir hack ama bunu yapıyorum:

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

Bunun $$vAngularJS tarafından kullanılan dahili bir değişken olduğunu biliyorum , ancak bizim için çözülmüş bir sözün göstergesi olarak oldukça güvenilirdi. AngularJS 1.2'ye yükselttiğimizde ne olacağını kim bilebilir: - / $q1.2 belgelerinde iyileştirmelerden bahsetmiyorum, ancak belki birisi Q'ya daha yakın daha iyi bir özelliğe sahip bir değiştirme hizmeti yazabilir.


Teşekkürler, ancak "özel" üyeler kullanmaktan daha iyi seçenekler var.
Jackson

0

Tam senaryonuzu bilmiyorum, ancak eşzamansız çağrıyı yaptıktan (ve sözü oluşturduktan) hemen sonra bir zaman aşımı koymak daha normaldir.

İfadenin setTimeout()eşzamansız çağrı ile aynı olay iş parçacığında olması koşuluyla, bir yarış etkisi olasılığı konusunda endişelenmenize gerek yoktur. JavaScript kesinlikle tek iş parçacıklı olduğundan, vaadin .then()geri aramalarının daha sonraki bir olay iş parçacığında tetiklenmesi garanti edilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.