Generator önceki yazıda gördüğümüz Symbol.iterator ile değişkenlere uygulanan mantığın fonksiyonlar ile kullanılmasını sağlayan ES6 ile javascriptte kullanılabilir olan bir özellik.
Bir fonksiyonu generator ile oluşturmak için function ile fonksiyon ismi arasına * işareti koyuyoruz.
function* log(){}
function *log(){}
function * log(){}
* işareti function ile ismi arasında herhangi bir yerde olabilir.
yield parametresi ile fonksiyonun aktarıldığı bir değişkenden .next fonksiyonu her çağırıldığında geri dönecek olan verileri yönetebiliyoruz.
function *log(){
yield 1;
yield 2;
yield 3;
}
const _ = log();
console.log(_.next());
console.log(_.next());
console.log(_.next());
console.log(_.next());
çıktı:
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
Yukarıda log adında bir fonksiyon tanımladık ve başına * koyarak generator kullanımı yapılacağını belirttik. Sonrasında yield ile belirttiğimiz her satır log fonksiyonu baz alınarak tanımlanan _ değişkeninde .next fonksiyonu her çağırıldığında geri dönüş olarak döndürüldü. 3 den sonra döndürülecek eleman kalmadığı için value undefined ve done true olarak döndü.
function *log(){
yield 1;
yield 2;
yield 3;
return 4;
}
const _ = log();
console.log(_.next());
console.log(_.next());
console.log(_.next());
console.log(_.next());
yield 1;
yield 2;
yield 3;
}
const _ = log();
console.log(_.next());
console.log(_.next());
console.log(_.next());
console.log(_.next());
çıktı:
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
Yukarıda log adında bir fonksiyon tanımladık ve başına * koyarak generator kullanımı yapılacağını belirttik. Sonrasında yield ile belirttiğimiz her satır log fonksiyonu baz alınarak tanımlanan _ değişkeninde .next fonksiyonu her çağırıldığında geri dönüş olarak döndürüldü. 3 den sonra döndürülecek eleman kalmadığı için value undefined ve done true olarak döndü.
function *log(){
yield 1;
yield 2;
yield 3;
return 4;
}
const _ = log();
console.log(_.next());
console.log(_.next());
console.log(_.next());
console.log(_.next());
çıktı:
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: true }
Birde return parametresini ekleyerek çağırdığımızda done true olduğu satırda return ün gönderdiği eleman geri döner.
.next fonksiyonuna veri göndererek geri dönüşleri yönetebiliriz.
function *topla(i){
const j = 2 * (yield i);
const k = (yield j * 2);
return i * j * k;
}
const _ = topla(2);
console.log(_.next());
console.log(_.next(4));
console.log(_.next(5));
çıktı:
{ value: 2, done: false }
{ value: 16, done: false }
{ value: 80, done: true }
- İlk olarak topla fonksiyonunu _ değişkenine aktarırken i parametresi olarak 2 yi gönderdik.
- yield fonksiyonun olduğu satırlar her çağırılmada sonraki çağrıya referans olurlar.
- .next fonksiyonun ilk çağırılmasında yield i 2 yi geri döndürdü.
- .next fonksiyonun ikinci çağırılmasında 4 gönderildiği için ilk yield 4 * 2 den 8 dönecek olan yield de 8 * 2 den 16 yı geri döndü.
- .next fonksiyonun son çağrısında 5 in gönderildiği yield 5 i geri döndü ve k 5 değerini aldı.
- i 2, j 8 ve k da 5 değerini aldığı için üçünün çarpımı 80 sonucunu geri döndü.
Önceki yazımızda gördüğümüz for..of ile generator function kullanımına bir örnek verelim.
function *log(){
yield 1;
yield 2;
yield 3;
return 4;
}
for(let i of log())
console.log(i);
çıktı:
1
2
3
for..of ile generator function kullanıldığında of dan önce tanımlanan değer .next fonksiyonunda geri dönen value değerini alır.
Bu yazıda generator function ile ilgili basit örnekler vererek ne olduğunu ve nasıl kullanıldığını anlatmaya çalıştım. Sonraki yazıda görüşmek üzere.
Hiç yorum yok:
Yorum Gönder