2015-07-23 27 views
10

So ... Meteor.defer(function(){ // stuff }) dokümanlarında değildir:Birisi Meteor.defer() işlevinin nasıl çalıştığını açıklayabilir mi?

https://github.com/meteor/meteor/issues/2176

Ama this bağlantılar Eğer durum buysa o

Meteor.setTimeout(function(){ // stuff }, 0); 

basitçe eşdeğer olduğunu söylemek görünüyor bu do nasıl yaptığını Bir şey var mı? Temelde "0 ms bekle ve sonra işlevi çalıştır" diyor.

Bu yüzden işlevi anında çalıştırır.

Burada nelerin eksik? Bu tür Tracker.afterFlush gibi bir şey mi? Çalışmadan önce bitirmek için "şeyler" (ne tür şeyler)?

cevap

17

I yüklü SO dom (biraz) sonra çalıştırmak için ilave bir yardımcı yöntemleri kesmek bir bit olarak kullanılan ilgili Meteor.defer() çok görmek - temelde Template.foo.rendered yöntem içinde kod çalıştıran aynı etkiyi elde etmek için . Ancak, Meteor.defer'un ana (ve en iyi) kullanımı asenkronize olarak numaralı bir görevi çalıştırmaktır.

Diyelim ki bir e-posta gönderdiğimiz bir uygulamamız var. Sunucuda, bir meteor yönteminin içinde işlem yapmak, uygulamanızı önemli ölçüde yavaşlatmak için birkaç saniye sürebilir. Ancak, bu işlemi Meteor.defere-posta işlemiyle yürütürseniz, e-posta işlemi yürütme işlemini yürütmeyi engelleyemez, e-posta gönderir (anında bir şans olduğunda anında gönderir), ancak her şey daha hızlı çalışır; bekleyen. Bulletproof Meteor numaralı telefondan yürütmeyi erteleme konusunda harika bir örnek ders var.

Aslında bir setTimeout(f,0) ile aynı etkiyi elde edebilirsiniz - yavaş bir işlevi varsa, bu nedenle 'Ertele'yı' zaman aşımı yavaş süreci, sen setTimeout bunu sarabilirdiniz ve kodun kalan tamamlayacak ve Göründüğü gibi, setTimeout(f,0) aslında oldukça yararlı bir amaca sahip!

Bu işlemin bir örneğini görmek için, here's a fiddle, konsolu açın ve 'foo' günlüklerinin nerede olduğunu izleyin.

+0

Yakaladım.Açıklama için teşekkürler. "Ertelemek", üçüncü taraf kodunu başlatmadan önce DOM öğelerinin yüklenmesini beklemek için kullanabileceğim bir şey olabileceğini düşündüm, çünkü bu yazı bundan bahseder - https://github.com/meteor/meteor/issues/2176 -: ' Meteor.defer() yöntemini düzenli olarak kullanıyorum. Herzaman, kodumda yürütmüyormuş gibi görünen bir talimatım var ve daha sonra konsolda aynı talimatı çalıştırıyorum ve çalışır, Meteor.defer() ile koduma koyarım ve genellikle çalışır. Tipik olarak, DOM’da bağlı olduğum bir şeyin henüz oluşturulmadığı durumlar görünüyor. ... ' – fuzzybabybunny

+0

Bir 'render' geri çağrısının etkisini elde etmek için nasıl kullanılacağını anlamıyorum. Eğer kod 'async' yani 'non-blocking' yapmak için 'defer' kullanırsanız, kod hemen bir şey beklemeden hemen yürütülür ... bir şeyin tamamlanmasını beklemenin tam tersidir (DOM render gibi). – fuzzybabybunny

+0

Aslında bir anlam ifade ediyor ... bir "erteleme" çalıştırması onu geçerli yürütme sırasından kaldırır ve js tek bir iş parçacığı olduğu için, yürütme sırasındaki her şey bittiğinde çalıştırılır - bu yüzden biraz çalışır. Gecikme (ilk yorumunuzda) ancak ikinci yorumunuzda derhal yürütme (çünkü tek iş parçacıklı). –

-1

Zaman uyumsuz geri arama nedeniyle projemde bir sorunla karşılaştım. onCreated içinde bir sunucu Meteor.call yapıyordum ve yanıtı reaiveVar içinde ayarlayın. Ve 'un içinde reaiveVar ile bir şeyler yapıyordum. Her zaman reaiveVar, tanımsız göstermekteydi.

onRendered'un içinde Meteor.defer(function(){...})'u kullandım ve bu sorunumu öğrendi. İşte

ile ve Meteor.defer()

Template.myTemplate.onCreated(function() { 
    var instance = this; 
    instance.myTemplateModel = new ReactiveDict(); 

    Meteor.call('all-user', function(err, res){ 
     if(res){ 
      console.log('inside callback'); 
      instance.myTemplateModel.set('users', res); 
     } 
    }); 
}); 

Template.myTemplate.onRendered(function() { 
    var instance = this 
    console.log('rendered start'); 
    Meteor.defer(function(){ 
     console.log(instance.myTemplateModel.get('users')); 
    }); 
    console.log('render end'); 
}); 

Konsolu kullanmadan bazı demo geçerli:

/*Without Meteor.defer()*/   | /*With Meteor.defer()*/ 
render start      | inside callback 
undefined       | render start 
render end       | render end 
inside callback     | [Object, Object, Object] 
+1

Ayrıca, bu tür eşzamansız yürütme sorununu çözmenin en iyi yollarından biri olduğunu varsayıyorum, bunun başkalarına yardımcı olabileceğini umuyorum. ve ayrıca başka olası yollar varsa bize bildirin ... mutlu kodlama. :) – iamhimadri

+1

-1 Bu sorun için soruyor ... Metot çağrısı yönteminin yeterince hızlı çalıştığı için şanslısınız (Eminim bir saptayım var). Ertelenmiş fonksiyonun, yöntemin geri çağrılmasından sonra çağrılacağından emin olmanın bir yolu yoktur. Ertelenmiş işlev, tüm planlanmış yürütmeler tamamlandıktan sonra çalışır. Sunucudan, ima etmeyi denediğiniz gibi bir cevap beklediğinizde, geri arama planlanmayacaktır. – Salketer

İlgili konular