AngularJS'de $ evalAsync ve $ timeout arasındaki fark nedir?


180

AngularJS'i bir süredir kullanıyorum ve arada bir $ timeout kullanma ihtiyacı buldum (Genellikle bir jQuery eklentisi başlatmak gibi görünüyor).

Son zamanlarda, sindirim döngüsünü daha iyi ve daha derinlemesine anlamaya çalışıyorum ve $ evalAsync işleviyle karşılaştım.

Bu fonksiyonun benzer sonuçlar ürettiği görülüyor $timeout, sadece siz geciktirmiyorsunuz. Her kullandığımda $timeout0'lık bir gecikmeyle oldu, bu yüzden şimdi kullanmam gerekip gerekmediğini merak ediyorum $evalAsync.

İkisi arasında herhangi bir temel fark var mı? Hangi vakaları diğerinin üzerinde kullanırsınız? Hangisini ne zaman kullanacağımı daha iyi hissetmek istiyorum.

Yanıtlar:


263

Kısa bir süre önce bu soruyu burada yanıtladı: https://stackoverflow.com/a/17239084/215945 (Bu cevap Misko ile bazı github borsalarına bağlanıyor.)

Özetlemek:

  • kod kullanılarak sıraya ise bir yönerge dan $ evalAsync , bu çalışmalıdır sonra DOM açısal tarafından manipüle edilmiş, ancak önce tarayıcı vermektedir
  • kod kullanılarak sıraya ise bir kumandadan gelen $ evalAsync , bu çalışmalıdır önce DOM açısal tarafından (ve tarayıcı görüntüleyen önce) manipüle edilmiştir - nadiren bu istiyorsun
  • kod kullanılarak sıraya ise $ zaman aşımı , bu çalışmalıdır sonra DOM açısal tarafından manipüle edilmiş ve sonra tarayıcı vermektedir (bazı durumlarda titreşimi neden olabilir)

15
Açıklama için teşekkürler. Bir şey olsa emin değilim. Bir denetleyiciden veya yönergeden $ evalAsync çağırıyorsanız neden bir fark yaratıyor? AsyncQueue bir denetleyiciden mi yoksa bir yönergeden mi kaydedildiğini bilmiyor, sadece geçerli kapsamda sıraya koyuyor. Bir denetleyicide bir şeyler denetleyiciye karşı çalıştığında bununla mı ilgili? Sadece o kısmı anlamak istiyorum.
dnc253

@ dnc253, Açısal koda bakmadım, bu yüzden (iyi) sorunuzun cevabını bilmiyorum. Umarım başka biri yorum yapabilir.
Mark Rajcok

15
"direktiften" ne demek "direktifin bağlama fonksiyonundan" ne demek? Yoksa bir direktifin bağlantı veya denetleyici yönteminden yürütüldüğünde davranış doğru mu?
SimplGy

5
evet, "bir direktiften" ve "bir denetleyiciden" burada ne anlama geldiği gerçekten belli değil
thorn̈

1
@MarkRajcok, lütfen burada açıklığa kavuşturabilirsiniz: kod bir yönergeden $ evalAsync kullanılarak sıraya alınmışsa, DOM, Açısal tarafından manipüle edildikten sonra çalıştırılmalıdır - DOM bu direktif tarafından manipüle edildikten sonra mı yoksa diğer direktiflerle mi çalıştırılmalıdır?
Max Koretskyi

59

Karmaşık uygulamalar geliştirenler için, seçiminizde bir performans etkisi olduğunu unutmayın. Ayrıca, Mark yanıtını daha teknik detaylarla tamamlamak istiyorum:

  • $ timeout (geri arama) mevcut özet döngüsünün yapılmasını bekleyecek (yani tüm modeli ve DOM'u açısal güncelleme), daha sonra geri çağrısını yürütecek - potansiyel olarak açısal modeli etkileyecek - daha sonra $applykök $ kapsamında bir tam başlatacak ve en küçüğü herşey.

  • $ evalAsync (geri arama) , geri çağrıyı geçerli veya sonraki özet döngüsüne ekler. ng-clickBaşka bir deyişle, bir özet döngüsünün içindeyseniz (örneğin, bazı yönergelerden çağrılan bir işlevde ), bu hiçbir şey beklemez, kod hemen yürütülür. Eşzamansız bir çağrının içindeyseniz, örneğin a setTimeout, yeni bir özet döngüsü ( $apply) tetiklenir.

Performanslar açısından, $evalAsynckodun yürütülmesinden önce görünümün güncel olması sizin için önemli değilse, örneğin eleman genişliği ve benzerleri gibi bazı DOm özniteliklerine erişmeniz gerekiyorsa , her zaman aramak daha iyidir .

$ Timeout, $ evalAsync, $ digest, $ Apply arasındaki fark hakkında daha fazla ayrıntı istiyorsanız, sizi bu soru hakkındaki cevabımı okumaya davet ediyorum: https://stackoverflow.com/a/23102223/1501926

Ayrıca belgeleri de okuduğunuzdan emin olun. :

$ EvalAsync, ifadenin ne zaman yürütüleceğine dair hiçbir garanti vermez, sadece:

  • değerlendirmeyi zamanlayan işlevden sonra (tercihen DOM oluşturma işleminden önce) yürütülür.
  • İfade yürütüldükten sonra en az bir $ digest döngüsü gerçekleştirilir.

Not: Bu işlev $ digest döngüsünün dışında çağrılırsa, yeni bir $ digest döngüsü programlanır . Ancak, modeli her zaman $ uygula çağrısından değiştiren çağrı kodunun kullanılması önerilir. Buna $ evalAsync aracılığıyla değerlendirilen kod da dahildir.


Bazı DOM özelliklerine erişmem gerekirse neden $ zaman aşımı gerektiğini açıklayabilir misiniz? Diyelim ki <table width = "{{x}}"> ng-bind'ın izleme işlevi bellekteki dom özniteliğini güncellemiyorsa, özet döngüsü çıkana kadar görünümü yeniden boyama şansı olmayacağını anlıyorum.
Sridhar Chidurala

2
@SridharChidurala, DOM ("HTML") özetleme döngüsü sırasında güncellendiğinden, değişiklikleri okuyabilmek için bunun gerçekleşmesini beklemeniz gerekir. Ancak bu Angular tarafından önerilmez x, DOM yerine doğrudan kapsamınızdan okumalısınız , bu yüzden hiçbir şey beklemenize gerek yoktur. Ayrıca, ng-styleeskimiş widthözellik yerine css ile daha iyi kullanmalısınız . Daha fazla yardıma ihtiyacınız olursa, lütfen StackOverflow ile ilgili yeni bir soru açın.
floribon
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.