Yazılım.
CevapSitesi.com Beta!
Çözüm Noktası
Facebook, Twitter, Google+ veya e-posta ile paylaşın.
| Sorular | Makaleler | Üyeler | Etiketler  | İletişim
Soru sormak ya da cevap vermek için;
giriş yapın veya üye olun.

Sosyal medya hesaplarınızla da giriş yapabilirsiniz.

Makale Geçmişi

«« Makaleye geri dön
27.09.20 01:20
JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions
(Bu yeni bir standarttır. Tüm tarayıcılarla uyumlu değildir. Ancak Node.js gibi bazı uygulamalarda çalışır.) Üretici fonksiyonlar bir yineleyici blok (döngü veya for .. of  gibi) içinden tekrarlı çağırıldıklarında ya da ayrı ayrı her çağırıldıklarında bir değer döndüren fonksiyonlardır. Döndürdüğü değerler genellikle birbiriyle ilgili bir dizinin elemanları, bir sayı silsilesinin sayıları gibi ardışık ve ilişkili değerlerdir. Uretici fonksiyon tanımlanırken  function  bildiriminin yanına veya fonksiyon adının önüne bir * karakteri konur. function* yineleyici() { ... } Bu fonksiyonlar değer döndürmek için  return    ifadesi yerine  yield   (teslim et) ifadesini kullanırlar. Her bir  yield , fonksiyonun çalışmasını durdurur ve çağıran fonksiyona bir değer döndürür. Üretici fonksiyonun sonraki çağılmasında son çalışan  yield 'den sonraki  yield  çalıştırılıp yanında belirtilen değer döndürülür ve bu şekilde devam eder. function* yineleyici() { yield 1 yield 3 yield 5 } Üretici fonksiyonları kullanabilmek ve  yield  ile veri döndürmesini sağlayabilmek için fonsiyon normal olarak çağırılır. Bu çağrıdan bir  Generator  nesnesi elde ederiz. Dönen  Generator  referans değeri bir değişkene atanır. Bunun ardından fonksiyondan değer almak için  Generator  örneğinin (değişkenin)  next  metodu çağırılır. var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. console.log(uretici.next()); // Sıradaki yield ile dönen değeri almak için Generator nesnesinin next metodunu çağır. next  metodu, çağırıldığında  value  ve  done  özelliklerine sahip basit bir nesne döndürür. Dönen nesneye örnek: { value:"2", done:false } Bu nesnedeki  value  (değer) özelliğinin değeri  yield  ile döndürülen değeri tutar.  done  (bitti, tamamlandı) özelliği ise üretici fonksiyon içinde son çalıştırılan  yield 'den sonra başka  yield  olup olmadığını döndürür. Bunu fonksiyonun yaptığı üretme işleminin bitip bitmediğini anlamak için kullanırız. Tam örnek: function* yineleyici() { yield 1; yield 3; yield 5; } var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. // İlk yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 1, done: false } nesnesini verir. // İkinci yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 3, done: false } nesnesini verir. // Üçüncü yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 5, done: false } nesnesini verir. var sonAlinanDeger = uretici.next(); // Başka yield olmadığından { value: undefined, done: true } nesnesi döner. console.log(sonAlinanDeger.value); // Başka yield olmadığından undefined değeri console.log(sonAlinanDeger.done); // Başka yield olmadığından true değeri Çıktısı: 1 3 5 undefined true Üretici fonksiyonlarda  yield  değer döndürmek zorunda değildir. Eğer sadece  yield  kullanılırsa  undefined  döndürür. Bu yüzden değere bakarak fonksiyonun döndüreceği değerlerin tamamlanıp tamamlanmadığını anlamaya çalışmayın. Bitip bitmediğini anlamak için  done  değerini test edin. Eğer hem değer almak ve hem de yinelemenin bittiğini haber almak isterseniz ilk ve son kez bir  return  ile değer döndürebilirsiniz.  return  ile değer döndürüldüğünde done değeri  true  olur. Ancak bundan sonra  next 'i kullanırsak hata ortaya çıkar. function* yineleyici() { yield 1; yield 3; return 5; } var uretici = yineleyici(); console.log(uretici.next().done); console.log(uretici.next().done); var sonAlinanDeger = uretici.next(); console.log(sonAlinanDeger.value); console.log(sonAlinanDeger.done); Çıktısı: false false 5 true Generator  nesnesine, dolayısıyla üretici fonksiyona parametre olarak değer gönderebiliriz. Bunun için  Generator  nesnesini elde etmek için fonksiyonu çağırdığınızda fonksiyona göndereceğiniz parametreyi de bildirin. function* yineleyici(carpan) { yield 1 * carpan; yield 3 * carpan; yield 5 * carpan; } var uretici = yineleyici(2); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 2 6 10 Üretici fonksiyondan oluşturulan her bir  Generator  nesnesi üretici fonksiyonun ayrı bir kopyasını çalıştıracaktır. function* yineleyici() { yield 1; yield 3, yield 5; } var uretici1 = yineleyici(); var uretici2 = yineleyici(); console.log(uretici1.next().value); console.log(uretici2.next().value); Çıktısı: 1 1 Üretici fonksiyonlar, başta da belirttiğimiz gibi ardışık ve alakalı bir değerler kümesinin elemanlarını tek tek döndürmek için uygundur. Bu örnek, Fibonacci dizisinin elemanlarını sırayla döndürür: function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 1 1 2 Üretici fonksiyonları yinelenebilir (iterable) olduğundan, bu tür sınıfların ( Array  ,  arguments  ,  String  vs.) elemanlarını gezmek için kullanılan  for ... of   döngüsüyle beraber kullanılabilir. function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); for (var sayi of uretici) // var yerine let de yazabilirsiniz. console.log(sayi); Çıktısı: 1 1 2 3 5 8 13 21 Üretici fonksiyonların sonraki tekrarını  next  ile çağırdığınızda fonksiyona bir değer gönderebilirsiniz. Bu parametre göndermekten farklıdır. Parametreyi sadece bir kez gönderebilirsiniz.  next  ile her seferinde fonksiyonun  yield  ile bekleyen satırına farklı bir değer gönderebilirsiniz. next  ile fonksiyona bir değer gönderildiğinde bu değer  yield  ile alınır. Burada şuna dikkat edin.  next  ile gönderilen değerin alınabilmesi için bekleten bir   yield  gereklidir . Yani hiç bekleten bir  yield  yoksa gönderdiğiniz değer bir işe yaramaz. Ama eğer bir kez  next  kullanmışsanız (varsa) bir  yield  bekliyordur. Bundan sonraki  next  çağırınızla gönderdiğiniz değer bekleyen  yield  ile döndürülecektir. Bu aşamada değeri bir değişkene atayabilir veya başka şekilde kullanabilirsiniz. function* selamla() { var adi = yield "Adınız?"; yield "Selam " + adi; } var uretici = selamla(); console.log(uretici.next().value); // "Adınız?" yazar. Bir sonraki next kullanımında fonksiyondaki adi değişkenine atanacak bir değer gönderilmeli. console.log(uretici.next("Ali").value); // "Selam Ali" yazar. İlk  next  çağrısının parametresiz yapıldığına dikkat edin. Bu çağrıyı bir  yield  bekletmesi oluşturmak için yaptık. İkinci  next  çağrımızda,  next  ile gönderdiğimiz "Ali" değeri bekleyen  yield 'in (ilk  yield  ) döndürdüğü bir sonuç olduğu için bunu  adi  değişkenine atadık. Ardından ikinci  yield  çalıştı ve selamlama metnini gönderdi. Bir üretici fonksiyon içinden başka bir üretici fonksiyonu çağırabilirsiniz. Bunun için  yield*   kullanılır. Bu durumda üretici fonksiyon içinden çağırılan üretici fonksiyonun  yield 'leri bitene kadar çağıran fonksiyon  yield*  satırında bekler. Örnek: function* deneme2() {     yield "a";     yield "b"; } function* deneme() {     yield 1;     yield* deneme2();     yield 2; } for (let deger of deneme())     console.log(deger); Çıktısı: 1 a b 2 Üretici fonksiyonlar yerinde çalıştırılan isimsiz fonksiyonlar olarak da yazılabilir. Üretici fonksiyonlar yapılandırıcı olarak kullanılamazlar. JavaScript Fonksiyonları ile İlgili Makaleler: JavaScript Fonksiyonları: Temel Kullanım JavaScript Fonksiyonları: Fonksiyonun Kendini Çağırması (Recursion) JavaScript Fonksiyonları: Fonksiyon İfadeler - Function Expressions JavaScript Fonksiyonları: Kapsanımlar - Closures Javascript Fonksiyonları: Yerinde Çalıştırılan İsimsiz Fonksiyonlar JavaScript Fonksiyonları: Nesne İçinde Fonksiyon - Metotlar JavaScript Fonksiyonları: Nesne Yapılandırıcısı Olarak Fonksiyon Kullanma JavaScript Fonksiyonları: this Kullanımı JavaScript Fonksiyonlari: arguments Nesnesi JavaScript Fonksiyonları: rest Parametreleri JavaScript Fonksiyonları: Function Yapılandırıcısı JavaScript Fonksiyonları: getter ve setter Fonksiyonlar JavaScript Fonksiyonları: Arrow (ok) Fonksiyonları JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions  (Bu makale)
Ekleyen: canora
Değiştiren: cevapsitesi
27.09.20 01:19
JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions
(Bu yeni bir standarttır. Tüm tarayıcılarla uyumlu değildir. Ancak Node.js gibi bazı uygulamalarda çalışır.) Üretici fonksiyonlar bir yineleyici blok (döngü veya for .. of  gibi) içinden tekrarlı çağırıldıklarında ya da ayrı ayrı her çağırıldıklarında bir değer döndüren fonksiyonlardır. Döndürdüğü değerler genellikle birbiriyle ilgili bir dizinin elemanları, bir sayı silsilesinin sayıları gibi ardışık ve ilişkili değerlerdir. Uretici fonksiyon tanımlanırken  function  bildiriminin yanına veya fonksiyon adının önüne bir * karakteri konur. function* yineleyici() { ... } Bu fonksiyonlar değer döndürmek için  return    ifadesi yerine  yield   (teslim et) ifadesini kullanırlar. Her bir  yield , fonksiyonun çalışmasını durdurur ve çağıran fonksiyona bir değer döndürür. Üretici fonksiyonun sonraki çağılmasında son çalışan  yield 'den sonraki  yield  çalıştırılıp yanında belirtilen değer döndürülür ve bu şekilde devam eder. function* yineleyici() { yield 1 yield 3 yield 5 } Üretici fonksiyonları kullanabilmek ve  yield  ile veri döndürmesini sağlayabilmek için fonsiyon normal olarak çağırılır. Bu çağrıdan bir  Generator  nesnesi elde ederiz. Dönen  Generator  referans değeri bir değişkene atanır. Bunun ardından fonksiyondan değer almak için  Generator  örneğinin (değişkenin)  next  metodu çağırılır. var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. console.log(uretici.next()); // Sıradaki yield ile dönen değeri almak için Generator nesnesinin next metodunu çağır. next  metodu, çağırıldığında  value  ve  done  özelliklerine sahip basit bir nesne döndürür. Dönen nesneye örnek: { value:"2", done:false } Bu nesnedeki  value  (değer) özelliğinin değeri  yield  ile döndürülen değeri tutar.  done  (bitti, tamamlandı) özelliği ise üretici fonksiyon içinde son çalıştırılan  yield 'den sonra başka  yield  olup olmadığını döndürür. Bunu fonksiyonun yaptığı üretme işleminin bitip bitmediğini anlamak için kullanırız. Tam örnek: function* yineleyici() { yield 1; yield 3; yield 5; } var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. // İlk yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 1, done: false } nesnesini verir. // İkinci yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 3, done: false } nesnesini verir. // Üçüncü yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 5, done: false } nesnesini verir. var sonAlinanDeger = uretici.next(); // Başka yield olmadığından { value: undefined, done: true } nesnesi döner. console.log(sonAlinanDeger.value); // Başka yield olmadığından undefined değeri console.log(sonAlinanDeger.done); // Başka yield olmadığından true değeri Çıktısı: 1 3 5 undefined true Üretici fonksiyonlarda  yield  değer döndürmek zorunda değildir. Eğer sadece  yield  kullanılırsa  undefined  döndürür. Bu yüzden değere bakarak fonksiyonun döndüreceği değerlerin tamamlanıp tamamlanmadığını anlamaya çalışmayın. Bitip bitmediğini anlamak için  done  değerini test edin. Eğer hem değer almak ve hem de yinelemenin bittiğini haber almak isterseniz ilk ve son kez bir  return  ile değer döndürebilirsiniz.  return  ile değer döndürüldüğünde done değeri  true  olur. Ancak bundan sonra  next 'i kullanırsak hata ortaya çıkar. function* yineleyici() { yield 1; yield 3; return 5; } var uretici = yineleyici(); console.log(uretici.next().done); console.log(uretici.next().done); var sonAlinanDeger = uretici.next(); console.log(sonAlinanDeger.value); console.log(sonAlinanDeger.done); Çıktısı: false false 5 true Generator  nesnesine, dolayısıyla üretici fonksiyona parametre olarak değer gönderebiliriz. Bunun için  Generator  nesnesini elde etmek için fonksiyonu çağırdığınızda fonksiyona göndereceğiniz parametreyi de bildirin. function* yineleyici(carpan) { yield 1 * carpan; yield 3 * carpan; yield 5 * carpan; } var uretici = yineleyici(2); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 2 6 10 Üretici fonksiyondan oluşturulan her bir  Generator  nesnesi üretici fonksiyonun ayrı bir kopyasını çalıştıracaktır. function* yineleyici() { yield 1; yield 3, yield 5; } var uretici1 = yineleyici(); var uretici2 = yineleyici(); console.log(uretici1.next().value); console.log(uretici2.next().value); Çıktısı: 1 1 Üretici fonksiyonlar, başta da belirttiğimiz gibi ardışık ve alakalı bir değerler kümesinin elemanlarını tek tek döndürmek için uygundur. Bu örnek, Fibonacci dizisinin elemanlarını sırayla döndürür: function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 1 1 2 Üretici fonksiyonları yinelenebilir (iterable) olduğundan, bu tür sınıfların ( Array  ,  arguments  ,  String  vs.) elemanlarını gezmek için kullanılan  for ... of   döngüsüyle beraber kullanılabilir. function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); for (var sayi of uretici) // var yerine let de yazabilirsiniz. console.log(sayi); Çıktısı: 1 1 2 3 5 8 13 21 Üretici fonksiyonların sonraki tekrarını  next  ile çağırdığınızda fonksiyona bir değer gönderebilirsiniz. Bu parametre göndermekten farklıdır. Parametreyi sadece bir kez gönderebilirsiniz.  next  ile her seferinde fonksiyonun  yield  ile bekleyen satırına farklı bir değer gönderebilirsiniz. next  ile fonksiyona bir değer gönderildiğinde bu değer  yield  ile alınır. Burada şuna dikkat edin.  next  ile gönderilen değerin alınabilmesi için bekleten bir   yield  gereklidir . Yani hiç bekleten bir  yield  yoksa gönderdiğiniz değer bir işe yaramaz. Ama eğer bir kez  next  kullanmışsanız (varsa) bir  yield  bekliyordur. Bundan sonraki  next  çağırınızla gönderdiğiniz değer bekleyen  yield  ile döndürülecektir. Bu aşamada değeri bir değişkene atayabilir veya başka şekilde kullanabilirsiniz. function* selamla() { var adi = yield "Adınız?"; yield "Selam " + adi; } var uretici = selamla(); console.log(uretici.next().value); // "Adınız?" yazar. Bir sonraki next kullanımında fornksiyondaki adi değişkenine atanacak bir değer gönderilmeli. console.log(uretici.next("Ali").value); // Selam Ali İlk  next  çağrısının parametresiz yapıldığına dikkat edin. Bu çağrıyı bir  yield  bekletmesi oluşturmak için yaptık. İkinci  next  çağrımızda,  next  ile gönderdiğimiz "Ali" değeri bekleyen  yield 'in (ilk  yield  ) döndürdüğü bir sonuç olduğu için bunu  adi  değişkenine atadık. Ardından ikinci  yield  çalıştı ve selamlama metnini gönderdi. Bir üretici fonksiyon içinden başka bir üretici fonksiyonu çağırabilirsiniz. Bunun için  yield*   kullanılır. Bu durumda üretici fonksiyon içinden çağırılan üretici fonksiyonun  yield 'leri bitene kadar çağıran fonksiyon  yield*  satırında bekler. Örnek: function* deneme2() {     yield "a";     yield "b"; } function* deneme() {     yield 1;     yield* deneme2();     yield 2; } for (let deger of deneme())     console.log(deger); Çıktısı: 1 a b 2 Üretici fonksiyonlar yerinde çalıştırılan isimsiz fonksiyonlar olarak da yazılabilir. Üretici fonksiyonlar yapılandırıcı olarak kullanılamazlar. JavaScript Fonksiyonları ile İlgili Makaleler: JavaScript Fonksiyonları: Temel Kullanım JavaScript Fonksiyonları: Fonksiyonun Kendini Çağırması (Recursion) JavaScript Fonksiyonları: Fonksiyon İfadeler - Function Expressions JavaScript Fonksiyonları: Kapsanımlar - Closures Javascript Fonksiyonları: Yerinde Çalıştırılan İsimsiz Fonksiyonlar JavaScript Fonksiyonları: Nesne İçinde Fonksiyon - Metotlar JavaScript Fonksiyonları: Nesne Yapılandırıcısı Olarak Fonksiyon Kullanma JavaScript Fonksiyonları: this Kullanımı JavaScript Fonksiyonlari: arguments Nesnesi JavaScript Fonksiyonları: rest Parametreleri JavaScript Fonksiyonları: Function Yapılandırıcısı JavaScript Fonksiyonları: getter ve setter Fonksiyonlar JavaScript Fonksiyonları: Arrow (ok) Fonksiyonları JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions  (Bu makale)
Ekleyen: canora
Değiştiren: cevapsitesi
27.06.16 00:47
JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions
(Bu yeni bir standarttır. Tüm tarayıcılarla uyumlu değildir. Ancak Node.js gibi bazı uygulamalarda çalışır.) Üretici fonksiyonlar bir yineleyici blok (döngü veya for .. of  gibi) içinden tekrarlı çağırıldıklarında ya da ayrı ayrı her çağırıldıklarında bir değer döndüren fonksiyonlardır. Döndürdüğü değerler genellikle birbiriyle ilgili bir dizinin elemanları, bir sayı silsilesinin sayıları gibi ardışık ve ilişkili değerlerdir. Uretici fonksiyon tanımlanırken  function  bildiriminin yanına veya fonksiyon adının önüne bir * karakteri konur. function* yineleyici() { ... } Bu fonksiyonlar değer döndürmek için  return    ifadesi yerine  yield   (teslim et) ifadesini kullanırlar. Her bir  yield , fonksiyonun çalışmasını durdurur ve çağıran fonksiyona bir değer döndürür. Üretici fonksiyonun sonraki çağılmasında son çalışan  yield 'den sonraki  yield  çalıştırılıp yanında belirtilen değer döndürülür ve bu şekilde devam eder. function* yineleyici() { yield 1 yield 3 yield 5 } Üretici fonksiyonları kullanabilmek ve  yield  ile veri döndürmesini sağlayabilmek için fonsiyon normal olarak çağırılır. Bu çağrıdan bir  Generator  nesnesi elde ederiz. Dönen  Generator  referans değeri bir değişkene atanır. Bunun ardından fonksiyondan değer almak için  Generator  örneğinin (değişkenin)  next  metodu çağırılır. var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. console.log(uretici.next()); // Sıradaki yield ile dönen değeri almak için Generator nesnesinin next metodunu çağır. next  metodu, çağırıldığında  value  ve  done  özelliklerine sahip basit bir nesne döndürür. Dönen nesneye örnek: { value:"2", done:false } Bu nesnedeki  value  (değer) özelliğinin değeri  yield  ile döndürülen değeri tutar.  done  (bitti, tamamlandı) özelliği ise üretici fonksiyon içinde son çalıştırılan  yield 'den sonra başka  yield  olup olmadığını döndürür. Bunu fonksiyonun yaptığı üretme işleminin bitip bitmediğini anlamak için kullanırız. Tam örnek: function* yineleyici() { yield 1; yield 3; yield 5; } var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. // İlk yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 1, done: false } nesnesini verir. // İkinci yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 3, done: false } nesnesini verir. // Üçüncü yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 5, done: false } nesnesini verir. var sonAlinanDeger = uretici.next(); // Başka yield olmadığından { value: undefined, done: true } nesnesi döner. console.log(sonAlinanDeger.value); // Başka yield olmadığından undefined değeri console.log(sonAlinanDeger.done); // Başka yield olmadığından true değeri Çıktısı: 1 3 5 undefined true Üretici fonksiyonlarda  yield  değer döndürmek zorunda değildir. Eğer sadece  yield  kullanılırsa  undefined  döndürür. Bu yüzden değere bakarak fonksiyonun döndüreceği değerlerin tamamlanıp tamamlanmadığını anlamaya çalışmayın. Bitip bitmediğini anlamak için  done  değerini test edin. Eğer hem değer almak ve hem de yinelemenin bittiğini haber almak isterseniz ilk ve son kez bir  return  ile değer döndürebilirsiniz.  return  ile değer döndürüldüğünde done değeri  true  olur. Ancak bundan sonra  next 'i kullanırsak hata ortaya çıkar. function* yineleyici() { yield 1; yield 3; return 5; } var uretici = yineleyici(); console.log(uretici.next().done); console.log(uretici.next().done); var sonAlinanDeger = uretici.next(); console.log(sonAlinanDeger.value); console.log(sonAlinanDeger.done); Çıktısı: false false 5 true Generator  nesnesine, dolayısıyla üretici fonksiyona parametre olarak değer gönderebiliriz. Bunun için  Generator  nesnesini elde etmek için fonksiyonu çağırdığınızda fonksiyona göndereceğiniz parametreyi de bildirin. function* yineleyici(carpan) { yield 1 * carpan; yield 3 * carpan; yield 5 * carpan; } var uretici = yineleyici(2); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 2 6 10 Üretici fonksiyondan oluşturulan her bir  Generator  nesnesi üretici fonksiyonun ayrı bir kopyasını çalıştıracaktır. function* yineleyici() { yield 1; yield 3, yield 5; } var uretici1 = yineleyici(); var uretici2 = yineleyici(); console.log(uretici1.next().value); console.log(uretici2.next().value); Çıktısı: 1 1 Üretici fonksiyonlar, başta da belirttiğimiz gibi ardışık ve alakalı bir değerler kümesinin elemanlarını tek tek döndürmek için uygundur. Bu örnek, Fibonacci dizisinin elemanlarını sırayla döndürür: function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 1 1 2 Üretici fonksiyonları yinelenebilir (iterable) olduğundan, bu tür sınıfların ( Array  ,  arguments  ,  String  vs.) elemanlarını gezmek için kullanılan  for ... of   döngüsüyle beraber kullanılabilir. function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); for (var sayi of uretici) // var yerine let de yazabilirsiniz. console.log(sayi); Çıktısı: 1 1 2 3 5 8 13 21 Üretici fonksiyonların sonraki tekrarını  next  ile çağırdığınızda fonksiyona bir değer gönderebilirsiniz. Bu parametre göndermekten farklıdır. Parametreyi sadece bir kez gönderebilirsiniz.  next  ile her seferinde fonksiyonun  yield  ile bekleyen satırına farklı bir değer gönderebilirsiniz. next  ile fonksiyona bir değer gönderildiğinde bu değer  yield  ile alınır. Burada şuna dikkat edin.  next  ile gönderilen değerin alınabilmesi için bekleten bir   yield  gereklidir . Yani hiç bekleten bir  yield  yoksa gönderdiğiniz değer bir işe yaramaz. Ama eğer bir kez  next  kullanmışsanız (varsa) bir  yield  bekliyordur. Bundan sonraki  next  çağırınızla gönderdiğiniz değer bekleyen  yield  ile döndürülecektir. Bu aşamada değeri bir değişkene atayabilir veya başka şekilde kullanabilirsiniz. function* selamla() { var adi = yield "Adınız?"; yield "Selam " + adi; } var uretici = selamla(); console.log(uretici.next().value); // Adınız? console.log(uretici.next("Ali").value); // Selam Ali İlk  next  çağrısının parametresiz yapıldığına dikkat edin. Bu çağrıyı bir  yield  bekletmesi oluşturmak için yaptık. İkinci  next  çağrımızda,  next  ile gönderdiğimiz "Ali" değeri bekleyen  yield 'in (ilk  yield  ) döndürdüğü bir sonuç olduğu için bunu  adi  değişkenine atadık. Ardından ikinci  yield  çalıştı ve selamlama metnini gönderdi. Bir üretici fonksiyon içinden başka bir üretici fonksiyonu çağırabilirsiniz. Bunun için  yield*   kullanılır. Bu durumda üretici fonksiyon içinden çağırılan üretici fonksiyonun  yield 'leri bitene kadar çağıran fonksiyon  yield*  satırında bekler. Örnek: function* deneme2() {     yield "a";     yield "b"; }
function* deneme() {     yield 1;     yield* deneme2();     yield 2; }
for (let deger of deneme())     console.log(deger); Çıktısı: 1 a b 2 Üretici fonksiyonlar yerinde çalıştırılan isimsiz fonksiyonlar olarak da yazılabilir. Üretici fonksiyonlar yapılandırıcı olarak kullanılamazlar. JavaScript Fonksiyonları ile İlgili Makaleler: JavaScript Fonksiyonları: Temel Kullanım JavaScript Fonksiyonları: Fonksiyonun Kendini Çağırması (Recursion) JavaScript Fonksiyonları: Fonksiyon İfadeler - Function Expressions JavaScript Fonksiyonları: Kapsanımlar - Closures Javascript Fonksiyonları: Yerinde Çalıştırılan İsimsiz Fonksiyonlar JavaScript Fonksiyonları: Nesne İçinde Fonksiyon - Metotlar JavaScript Fonksiyonları: Nesne Yapılandırıcısı Olarak Fonksiyon Kullanma JavaScript Fonksiyonları: this Kullanımı JavaScript Fonksiyonlari: arguments Nesnesi JavaScript Fonksiyonları: rest Parametreleri JavaScript Fonksiyonları: Function Yapılandırıcısı JavaScript Fonksiyonları: getter ve setter Fonksiyonlar JavaScript Fonksiyonları: Arrow (ok) Fonksiyonları JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions  (Bu makale)
Ekleyen: canora
Değiştiren: canora
19.06.16 14:34
JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions
(Bu yeni bir standarttır. Tüm tarayıcılarla uyumlu değildir. Ancak Node.js gibi bazı uygulamalarda çalışır.) Üretici fonksiyonlar bir yineleyici blok (döngü veya for .. of  gibi) içinden tekrarlı çağırıldıklarında ya da ayrı ayrı her çağırıldıklarında bir değer döndüren fonksiyonlardır. Döndürdüğü değerler genellikle birbiriyle ilgili bir dizinin elemanları, bir sayı silsilesinin sayıları gibi ardışık ve ilişkili değerlerdir. Uretici fonksiyon tanımlanırken  function  bildiriminin yanına veya fonksiyon adının önüne bir * karakteri konur. function* yineleyici() { ... } Bu fonksiyonlar değer döndürmek için  return    ifadesi yerine  yield   (teslim et) ifadesini kullanırlar. Her bir  yield , fonksiyonun çalışmasını durdurur ve çağıran fonksiyona bir değer döndürür. Üretici fonksiyonun sonraki çağılmasında son çalışan  yield 'den sonraki  yield  çalıştırılıp yanında belirtilen değer döndürülür ve bu şekilde devam eder. function* yineleyici() { yield 1 yield 3 yield 5 } Üretici fonksiyonları kullanabilmek ve  yield  ile veri döndürmesini sağlayabilmek için fonsiyon normal olarak çağırılır. Bu çağrıdan bir  Generator  nesnesi elde ederiz. Dönen  Generator  referans değeri bir değişkene atanır. Bunun ardından fonksiyondan değer almak için  Generator  örneğinin (değişkenin)  next  metodu çağırılır. var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. console.log(uretici.next()); // Sıradaki yield ile dönen değeri almak için Generator nesnesinin next metodunu çağır. next  metodu, çağırıldığında  value  ve  done  özelliklerine sahip basit bir nesne döndürür. Dönen nesneye örnek: { value:"2", done:false } Bu nesnedeki  value  (değer) özelliğinin değeri  yield  ile döndürülen değeri tutar.  done  (bitti, tamamlandı) özelliği ise üretici fonksiyon içinde son çalıştırılan  yield 'den sonra başka  yield  olup olmadığını döndürür. Bunu fonksiyonun yaptığı üretme işleminin bitip bitmediğini anlamak için kullanırız. Tam örnek: function* yineleyici() { yield 1; yield 3; yield 5; } var uretici = yineleyici(); // Bir Generator nesnesi döndürür. Değişkene atıyoruz. // İlk yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 1, done: false } nesnesini verir. // İkinci yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 3, done: false } nesnesini verir. // Üçüncü yield'i çalıştır, dönen nesnenin value değerini yaz. console.log(uretici.next().value); // next, { value: 5, done: false } nesnesini verir. var sonAlinanDeger = uretici.next(); // Başka yield olmadığından { value: undefined, done: true } nesnesi döner. console.log(sonAlinanDeger.value); // Başka yield olmadığından undefined değeri console.log(sonAlinanDeger.done); // Başka yield olmadığından true değeri Çıktısı: 1 3 5 undefined true Üretici fonksiyonlarda  yield  değer döndürmek zorunda değildir. Eğer sadece  yield  kullanılırsa  undefined  döndürür. Bu yüzden değere bakarak fonksiyonun döndüreceği değerlerin tamamlanıp tamamlanmadığını anlamaya çalışmayın. Bitip bitmediğini anlamak için  done  değerini test edin. Eğer hem değer almak ve hem de yinelemenin bittiğini haber almak isterseniz ilk ve son kez bir  return  ile değer döndürebilirsiniz.  return  ile değer döndürüldüğünde done değeri  true  olur. Ancak bundan sonra  next 'i kullanırsak hata ortaya çıkar. function* yineleyici() { yield 1; yield 3; return 5; } var uretici = yineleyici(); console.log(uretici.next().done); console.log(uretici.next().done); var sonAlinanDeger = uretici.next(); console.log(sonAlinanDeger.value); console.log(sonAlinanDeger.done); Çıktısı: false false 5 true Generator  nesnesine, dolayısıyla üretici fonksiyona parametre olarak değer gönderebiliriz. Bunun için  Generator  nesnesini elde etmek için fonksiyonu çağırdığınızda fonksiyona göndereceğiniz parametreyi de bildirin. function* yineleyici(carpan) { yield 1 * carpan; yield 3 * carpan; yield 5 * carpan; } var uretici = yineleyici(2); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 2 6 10 Üretici fonksiyondan oluşturulan her bir  Generator  nesnesi üretici fonksiyonun ayrı bir kopyasını çalıştıracaktır. function* yineleyici() { yield 1; yield 3, yield 5; } var uretici1 = yineleyici(); var uretici2 = yineleyici(); console.log(uretici1.next().value); console.log(uretici2.next().value); Çıktısı: 1 1 Üretici fonksiyonlar, başta da belirttiğimiz gibi ardışık ve alakalı bir değerler kümesinin elemanlarını tek tek döndürmek için uygundur. Bu örnek, Fibonacci dizisinin elemanlarını sırayla döndürür: function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); console.log(uretici.next().value); console.log(uretici.next().value); console.log(uretici.next().value); Çıktısı: 1 1 2 Üretici fonksiyonları yinelenebilir (iterable) olduğundan, bu tür sınıfların ( Array  ,  arguments  ,  String  vs.) elemanlarını gezmek için kullanılan  for ... of   döngüsüyle beraber kullanılabilir. function* fibonacci() { var dizi = [1, 1, 2, 3, 5, 8, 13, 21]; for (var i=0; i<dizi.length; i++) yield dizi[i]; } var uretici = fibonacci(); for (var sayi of uretici) // var yerine let de yazabilirsiniz. console.log(sayi); Çıktısı: 1 1 2 3 5 8 13 21 Üretici fonksiyonların sonraki tekrarını  next  ile çağırdığınızda fonksiyona bir değer gönderebilirsiniz. Bu parametre göndermekten farklıdır. Parametreyi sadece bir kez gönderebilirsiniz.  next  ile her seferinde fonksiyonun  yield  ile bekleyen satırına farklı bir değer gönderebilirsiniz. next  ile fonksiyona bir değer gönderildiğinde bu değer  yield  ile alınır. Burada şuna dikkat edin.  next  ile gönderilen değerin alınabilmesi için bekleten bir   yield  gereklidir . Yani hiç bekleten bir  yield  yoksa gönderdiğiniz değer bir işe yaramaz. Ama eğer bir kez  next  kullanmışsanız (varsa) bir  yield  bekliyordur. Bundan sonraki  next  çağırınızla gönderdiğiniz değer bekleyen  yield  ile döndürülecektir. Bu aşamada değeri bir değişkene atayabilir veya başka şekilde kullanabilirsiniz. function* selamla() { var adi = yield "Adınız?"; yield "Selam " + adi; } var uretici = selamla(); console.log(uretici.next().value); // Adınız? console.log(uretici.next("Ali").value); // Selam Ali İlk  next  çağrısının parametresiz yapıldığına dikkat edin. Bu çağrıyı bir  yield  bekletmesi oluşturmak için yaptık. İkinci  next  çağrımızda,  next  ile gönderdiğimiz "Ali" değeri bekleyen  yield 'in (ilk  yield  ) döndürdüğü bir sonuç olduğu için bunu  adi  değişkenine atadık. Ardından ikinci  yield  çalıştı ve selamlama metnini gönderdi. Bir üretici fonksiyon içinden başka bir üretici fonksiyonu çağırabilirsiniz. Bunun için  yield*   kullanılır. Bu durumda üretici fonksiyon içinden çağırılan üretici fonksiyonun  yield 'leri bitene kadar çağıran fonksiyon  yield*  satırında bekler. Örnek: function* deneme2() {     yield "a";     yield "b"; } function* deneme() {     yield 1;     yield* deneme2();     yield 2; } for (let deger of deneme())     console.log(deger); Çıktısı: 1 a b 2 Üretici fonksiyonlar yerinde çalıştırılan isimsiz fonksiyonlar olarak da yazılabilir. Üretici fonksiyonlar yapılandırıcı olarak kullanılamazlar. JavaScript Fonksiyonları ile İlgili Makaleler: JavaScript Fonksiyonları: Temel Kullanım JavaScript Fonksiyonları: Fonksiyonun Kendini Çağırması (Recursion) JavaScript Fonksiyonları: Fonksiyon İfadeler - Function Expressions JavaScript Fonksiyonları: Kapsanımlar - Closures Javascript Fonksiyonları: Yerinde Çalıştırılan İsimsiz Fonksiyonlar JavaScript Fonksiyonları: Nesne İçinde Fonksiyon - Metotlar JavaScript Fonksiyonları: Nesne Yapılandırıcısı Olarak Fonksiyon Kullanma JavaScript Fonksiyonları: this Kullanımı JavaScript Fonksiyonlari: arguments Nesnesi JavaScript Fonksiyonları: rest Parametreleri JavaScript Fonksiyonları: Function Sınıfı JavaScript Fonksiyonları: getter ve setter Fonksiyonlar JavaScript Fonksiyonları: Arrow (ok) Fonksiyonları JavaScript Fonksiyonları: Üretici Fonksiyonlar - Generator Functions  (Bu makale)
Ekleyen: canora
Değiştiren: canora

En fazla 3 eski durum gösterilir.