2017-08-15 28 views
5

Ben generator functions on MDN üzerinde tökezledi ve hangi Kafamı kurcalayan şu örnektir:Neden javascript üreteci işlevi döndürme işlevi .next() parametrelerini döndürüyor?

function* logGenerator() { 
    console.log(yield); 
    console.log(yield); 
    console.log(yield); 
} 

var gen = logGenerator(); 

// the first call of next executes from the start of the function 
// until the first yield statement 
gen.next(); 
gen.next('pretzel'); // pretzel 
gen.next('california'); // california 
gen.next('mayonnaise'); // mayonnaise 

Ne anlamıyorum console.log ait argümanı yield deyimi jeneratörün .next() yönteme geçirilen parametre döner yüzden . Bu oluyor mu, boş bir yield.next() yönteminin ilk parametresinin değerini döndürmelidir?

gen.next(1,2,3); // the printed value is 1, the 2 and 3 are ignored 
// and the actual yielded value is undefined 

Ayrıca jeneratör fonksiyonunun vücudun içinde .next() yöntemin diğer parametreleri erişmek için bir yol vardır:

Ben de böyle yukarıdaki ifadeyi doğrular niteliktedir biraz daha örnek, denediniz mi? Fark ettiğim başka bir şey ise, verim beyanı bu değerleri console.log'a döndürürken, aslında jeneratörün çıkışı olarak üretilmezler. Çok kafa karıştırıcı olduğunu söylemeliyim.

+0

... çünkü olması gereken şey bu mu? Bu neden kafanızı karıştırıyor? – user2357112

+0

Bu, bir "verim" ifadesinin değerlendirdiği şeydir. – user2357112

+0

@ user2357112 Beni şaşırtıyor çünkü yukarıdaki kodda başvurulan parametreyi göremiyorum. Cevaplardan gelen bağlantıları okuduğumda, şimdi her şey anlamlıdır ama ilk gördüğümde bunu anlamadım. Bir yan not olarak, aynı zamanda 'function * x() {getiri verimi;} – Jakub

cevap

2

Harika bir soru. Ben .next() yönteminde MDN okuma en yararlı olduğunu düşünüyorum. Sen ona bağlı value bir mantıksal ile gen.next(1)

kendisi bir nesne döndürür next() operatör gibi bir şey söyleyerek Eğer next() aracılığıyla değerini jeneratör işlevi (yani yield 1) kendisi içinde geçmesi veya iletmek istediğiniz değeri tanımlayabilirsiniz Tüm jeneratör fonksiyonunun bitip bitmediğini belirtmek için done. Ve value'a erişmenin/iletmenin iki yolu vardır.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next

0

This makes it quite clear:

[rv] = verim [sentezleme];

sentezleme yineleyici protokolü ile jeneratör işlevi dönmek değerini tanımlar. Atlanırsa, tanımsız olarak döndürülür. yürütme devam jeneratörün aşağıdaki() yöntemine iletilen isteğe bağlı değeri döndürür

rv.

Temel olarak, yürütmeye devam etmek için gönderdiğiniz parametreyi yazdırıyorsunuz.

1

karışıklık aslında aynı şeyi yapmak iken yield ve next, farklı sözdizimi sahip olmasından kaynaklanır. Jeneratör ve arayıcısı simetriktir (bu yüzden "co" -proutinler olarak adlandırılırlar ve "alt" -proutinler değil). Her iki işlev de bir iletişim kanalıyla bağlantılı olarak düşünülebilir ve işlerini yapabilir veya kanalda gelen bir mesajı bekleyerek uyuyabilir. Aradaki fark, uyancı başlangıçta uyanıkken, başlangıçta uykuda (yani, üstte örtük bir "dinle" komutu var) olmasıdır.

  • kanala
  • sonbahar uykuda onun argüman yazıp
  • değeri olarak gelen mesaj yayarlar, gelen bir iletiyi dinlemek:

    Hem yield

    ve next aynı şeyi üç şey yapması ve uyandırın (yani, bunların altında olanlarla devam edin)

Çizim: 012 yazma önce okuduğu geliyor çünkü jeneratöre gönderilen ilk mesaj kayıp olduğunu

_ = console.log.bind(console) 
 

 
function *gen() { 
 
    _('gen: good morning') 
 

 
    _('gen: sending hi') 
 
    _('gen: zzz') 
 
    p = yield 'hi' 
 
    _('gen: awake! got', p) 
 

 
    _('gen: now sending fine') 
 
    _('gen: zzz') 
 
    p = yield 'fine' 
 
    _('gen: awake! got', p) // *** 
 
} 
 

 
function main() { 
 

 
    var g = gen() 
 

 
    _('main: sending knock knock') 
 
    _('main: zzz') 
 
    r = g.next('knock knock') 
 
    _('main: awake! got', r) 
 

 
    _('main: sending how r u') 
 
    _('main: zzz') 
 
    r = g.next('how r u') 
 
    _('main: awake! got', r) 
 
} 
 

 
main()

Not. Sadece jeneratörü uyandırmak için kullanılır. Ayrıca, jeneratörü uyku durumunda bıraktığımıza dikkat edin, böylece *** hattına ulaşılamıyor.