javascript Generator Fonksiyon Kullanımı
Normal bir fonksiyon, görevini tamamlayana kadar, yani son satırı çalıştırılana kadar yürütme sırasında durdurulamaz. Buna tamamlama modeli denir.
function normalFonksiyon() {
console.log('birinci satır')
console.log('ikinci satır')
console.log('üçüncü satır')
console.log('son satır')
}
NormalFonksiyon
'dan çıkmanın tek yolu onu sonuna kadar çalıştırmak, return
kullanmak veya bir hatayla karşılaşmaktır. Fonksiyonu tekrar çağırırsanız, tekrar yukarıdan çalışmaya başlar.
Bunun aksine, bir Generator yarı yolda durabilen ve ardından kaldığı yerden devam edebilen bir fonksiyondur.
Generatör fonksiyonumuzu tanımlarken normal fonksiyona ek olarak, * (yıldız) karakterini kullanmamız gerekiyor.
const generator = function* () {}
function* test() {}
Fonksiyon anahtar sözcüğü ve parentez arasına bir yıldız işareti (*) yerleştirilebilir, bu nedenle aşağıdaki yöntem de geçerlidir.
const generator = function * () {}
const generator = function *() {}
function * test() {}
function *test() {}
Üreteçler bir nesnenin veya sınıfın yöntemleri bile olabilir:
//Bir nesnenin yöntemi olarak Generator
const generatorObj = {
*generatorMethod() {},
}
// Bir sınıfın yöntemi olarak Generator
class GeneratorClass {
*generatorMethod() {}
}
New
anahtar sözcük kullanılarak oluşturulamaz ve ok
işlevleriyle birlikte kullanılamaz.Generatör nesneleri
Genellikle JavaScript'teki fonksiyonlar tamamlanmadan önce çalıştırılır ve fonksiyon çağrısı anahtar sözcüğe ulaştığında bir değer döndürür (return). Anahtar kelime eksikse , fonksiyon değeri return undefined
döndürecektir.
Örneğin, aşağıdaki kodda, sum()
iki tamsayı argümanının toplamını döndüren bir fonksiyon bildiriyoruz:
// İki değeri toplayan normal işlem
function sum(a, b) {
return a + b
}
Fonksiyon çağrısı, bağımsız değişkenlerin toplamı olan bir değer döndürür:
const value = sum(5, 6) // 11
Ancak, Generator fonksiyon hemen bir değer döndürmez, bunun yerine Generator yinelemeyi destekleyen bir öğe döndürür. Aşağıdaki örnekte, tıpkı standart bir fonksiyon gibi bir fonksiyon bildirip ona bir dönüş(Return) değeri veriyoruz:
// Tek bir dönüş değeri olan bir üretici fonksiyon bildirin
function* generatorFunction() {
return 'Hello, Generator!'
}
Oluşturucu fonksiyonu etkinleştirmek, Generator bir değişkene başvurabileceğimiz bir öğe döndürür(return) :
// Generator nesnesini generator değişkenine atayın
const generator = generatorFunction()
Generatör fonksiyonları
Bir Generator oluşturmak için özel bir sözdizimi yapısına ihtiyacımız var: function*
sözde "Generator fonksiyonu". Şöyle görünüyor:
function *generator(){
yield 1;
yield 2;
yield 3;
yield 4;
}
Generator fonksiyonları normal fonksiyonlardan farklı davranır. Böyle bir fonksiyon çağrıldığında, kodlarını çalıştırmaz. Bunun yerine, yürütmeyi yönetmek için "oluşturucu nesne" adı verilen özel bir nesne döndürür. İşte, bir örnek:
function* generator() {
yield 1;
yield 2;
yield 3;
yield 4;
}
// Generatör fonksiyonu 'oluşturucu nesnesi' oluşturur.
let iterator = generator();
alert(iterator); // [object Generator]
Bir Generatörün ana yöntemi next()
. Çağrıldığında, yürütmeyi en yakın yield value
ifadeye kadar çalıştırır ( value ihmal edilebilir, değer undefined olur). Ardından, fonksiyonun yürütülmesi durur.
Sonuç next()
her zaman iki özelliğe sahip bir nesnedir:
- value: ortaya çıkan değer.
- done: true fonksiyon kodu bitmişse, aksi halde false.
function* generator() {
yield 1;
yield 2;
yield 3;
yield 4;
}
let iterator = generator();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
ÇIKTI:
Object {"value": 1, "done": false} Object {"value": 2, "done": false} Object {"value": 3, "done": false} Object {"value": 4, "done": false} Object { value: undefined, done: true }
Direk value değerlerini yazdırmak için next.value
kodunu yazın.
function* generator() {
yield 1;
yield 2;
yield 3;
yield 4;
}
let iterator = generator();
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
ÇIKTI:
1 2 3 4
Muhtemelen tahmin ettiğiniz gibi, Generatör fonksiyonun her çağrı için, bize bir sonraki yinelemeyi döndürür, yani, oluşturucuda tanımlanmış üç yinelememiz var:
function* generator_function(){
yield 1;
yield 2;
yield 3;
}
Generatör fonksiyonun üç kez çağırıyoruz ve geri döndüğünde hemen konsola veri yazıyor:
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);
Ayrıca, herhangi bir şeyi iade etmeden, değerleri Generatörün kendisi aracılığıyla konsola yazdırıyoruz:
function* generator_function(){
console.log(1);
yield;
console.log(2);
yield;
console.log(3);
yield;
}
var generator = generator_function();
generator.next();
generator.next();
generator.next();
Sonuç tam olarak aynı olacak.
Bir fonksiyonun başa çıkması gereken sonsuz bir girdi veya çıktı olsaydı ne olacağını hiç hayal ettiniz mi? Generator fonksiyonları başa çıkabileceğiniz problem tam olarak budur.
Bir Generator fonksiyonu bize ortadaki fonksiyon durdurmak, bir şeyler yapmak ve ardından her zaman devam ettirmek için kullanılabilecek bir yineleyici döndürür. Normal bir fonksiyon, fonksiyon tamamlandığında çalışmaya başlar ve geri(returnla veri) döner, ancak bir Generator fonksiyonu herhangi bir sayıda durdurulabilir ve daha sonra devam ettirilebilir.
Generator fonksiyonları return
ifade ile sonlandırabiliriz.
function* generator() {
yield 1;
yield 2;
return 3;
yield 4;
}
let iterator = generator();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
ÇIKTI:
Object { value: 1, done: false } Object { value: 2, done: false } Object { value: 3, done: true } Object { value: undefined, done: true }
Yukarıdaki örnekte görüldüğü üzere return ifadesi ile done: true
döngü sonlanmıştır sonraki ifadenin value değeri undefined
.
Generatörler Yinelenebilir
Muhtemelen next()
yönteme baktığınızı tahmin ettiğiniz gibi , Generator ifadeler yinelenebilir. for..of
kullanarak değerleri üzerinde döngü oluşturabiliriz:
function* uretec() {
yield 1;
yield 2;
yield 3;
return 4;
}
let generator = uretec();
for(let value of generator) {
console.log(value); //1 2 3
}
Yukarıdaki örnek 1,2 ve 3 gösterir; 4'ü göstermez. for..of
yinelemenin tamamlandığında son değeri yok saymasıdır: true. Dolayısıyla, tüm sonuçların for..of
tarafından gösterilmesini istiyorsak, bunları yield
ile döndürmeliyiz:
Ancak, bu yinelemeyi bir diziye dönüştürmek istiyorsanız, for-of
kullanmanıza gerek yoktur; bunun yerine spread
sözdizimi kodu kullanabilirsiniz.
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
return 4;
}
const iterator = generatorFunction();
const fromiterable = [...iterator];
console.log(fromiterable); // [1, 2, 3]
Sonsuz Veri Akışı
Generator kullanışlı yönlerinden biri, sonsuz akışlar ve veri koleksiyonları ile çalışma yeteneğidir. Sayıyı 1 artıran bir Generatör fonksiyonu içindeki sonsuz döngü örneğinde görülebilir.
Aşağıdaki kodlarda, bir Generatör fonksiyonu tanımlıyoruz ve ardından oluşturucuyu başlatıyoruz:
// Birer birer artan bir Generatör fonksiyonu tanımlayın
function* incrementer() {
let i = 0
while (true) {
yield i++
}
}
// Jeneratörü başlatın
const counter = incrementer();
// Değerleri yineleyin
console.log(counter.next());
console.log(counter.next());
console.log(counter.next());
console.log(counter.next());
ÇIKTI:
Object { value: 0, done: false } Object { value: 1, done: false } Object { value: 2, done: false } Object { value: 3, done: false }
Generator fonksiyonları kullanırken, uygun gördüğünüz şekilde yürütmeyi durdurup devam ettirebileceğiniz için sonsuz bir döngü oluşturma konusunda endişelenmenize gerek yoktur. Ancak yine de Generatörü nasıl aktive ettiğinize dikkat etmelisiniz. spread
işlecini veya for...of
sonsuz bir veri akışını kullanırsanız, aynı anda sonsuz bir döngü üzerinde yineleme yaparsınız ve bu da ortamın başarısız olmasına(hatalar çıkmasına) neden olur.
Generator fonksiyon içinde Generator Çağırma
Generator fonksiyonların içinde Generator fonksiyon çağrılır.
function *Generator() {
yield 1;
yield* anotherGenerator();
yield 3;
}
function *anotherGenerator() {
yield 2;
}
let iterator = generator();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
ÇIKTI:
{value: 1, done: false} {value: 2, done: false} {value: 3, done: false} {value: undefined, done: true}
ÖRNEK 2:
function *asilGenerator(name) {
yield `Başka Bir Generator, ${name}`
}
function *myGenerator(name) {
yield `Merhaba ${name}`;
yield* asilGenerator(name)
yield 'Gülegüle'
}
let gen = myGenerator('Mehmet')
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
ÇIKTI:
Merhaba Mehmet Başka Bir Generator. Mehmet Gülegüle
Bağımsız değişkenleri Generatore iletme
Argümanları Generatörlere aktarabiliriz.
function* logGenerator(i) {
while(i < 3)
{
console.log(i++, yield);
}
}
var gen = logGenerator(0);
// next yürütmenin ilk çağrısı fonksiyonun başlangıcından itibaren
//ilk verim tablosuna kadar
gen.next();
gen.next('Günlük kaydı başlıyor...');
gen.next('Günlük kaydı devam ediyor...');
gen.next('Günlük Kaydı Bitiyor...');
ÇIKTI:
0 "Günlük kaydı başlıyor..." 1 "Günlük kaydı devam ediyor..." 2 "Günlük Kaydı Bitiyor..."
ÖRNEK 2:
function* getNumber(){
let n = yield 5;
console.log("n:", n);
let m = yield 25 * n;
console.log("m:", m);
yield 125 * m;
}
let numberGenerator = getNumber();
console.log(numberGenerator.next().value);
console.log(numberGenerator.next(2).value);
console.log(numberGenerator.next(3).value);
ÇIKTI:
5 n :2 50 n:3 375
ÖRNEK 3:
function *myGenerator() {
console.log('Hey ', yield)
console.log('Are you ',yield)
}
let gen = myGenerator()
gen.next()
gen.next('Metin')
gen.next('Ahmet')
ÇIKTI:
Hey Metin Are you Ahmet
generator.throw
Hata iletmek için yield
aramamız gerekiyor generator.throw(err)
. Bu durumda, err
ile satıra bir istisna atılacaktır.
Örneğin, bu yield "2 + 2 = ?"bir hatayla sonuçlanacaktır:
function* generate() {
let result = yield "2 + 2 = ?"; // Bu satırda hata
}
let generator = generate();
let question = generator.next().value;
try {
generator.throw(new Error("Veritabanımda cevap bulunamadı"));
} catch(e) {
alert(e); // Bir hata gösterecek
}
ÖRNEK 2:
function* nums() {
try {
yield 1; // A
yield 2; // B
yield 3; // C
} catch (e) {
console.log(e.message); // D
}
}
var generator = nums();
generator.next(); // A satırını çalıştırarak { value: 1, done: false }
generator.next(); // B satırını çalıştırarak { value: 2, done: false }
generator.throw(new Error("Error!!")); // D satırını çalıştırarak { value: undefined, done: true}
// console: "Error!!"
generator.next(); // hiçbir kod yürütülmedi. Çıktılar { value: undefined, done: true }
Bir dosya veya veritabanından veri yüklemiş olmanız ve bilgileri ekranda aşamalı olarak görüntülemek isteyebilirsiniz. Verilerden bir yineleyici(döngü) oluşturabilir ve olay her gerçekleştiğinde birkaç öğeyi almak için bir olay fonksiyonu ayarlayabilirsiniz. Bu, böyle bir uygulamanın nasıl görünebileceğine dair bir örnektir:
let posts = load(url);
let it = posts[Symbol.iterator]();
function loadPosts(iterable, count) {
for (let i = 0; i < count; i++) {
display(iterable.next().value);
}
}
document.getElementById('btnNext').onclick = loadPosts(sayi, 5);
SONUÇ:
Generator Fonksiyonu : Bir Generator fonksiyon normal bir fonksiyon olarak tanımlanır, ancak bir değer üretmesi gerektiğinde, bunu return değil, Yield
anahtar sözcüğünü kullanarak yapar. Yield
ifadesi, fonksiyonun yürütülmesini duraklatır ve değeri arayana geri gönderir, ancak fonksiyonun kaldığı yerden devam etmesi için yeterli durumu korur. Bir kez sürdürüldüğünde, fonksiyonun, Yield
son çalışmasından hemen sonra çalışmaya devam eder.
Generatörler sonsuz bir şekilde değer üretebilir.
Tabi ki, böyle bir oluşturucuda bir döngüde break(veya return)
ihtiyacımız var. Aksi takdirde for..of
döngü sonsuza kadar devam edecek ve komut dosyası "askıda kalacak".
Herhangi bir listeyi yinelemeye(döngüye) ihtiyaç duydunuz mu, ancak işlemi tamamlamak çok zaman aldı mı? Bir işlem çok fazla bellek kullandığı için hiç program çöktü mü? Bu, asal sayılar üreten bir fonksiyonu uygulamaya çalıştığımızda başımıza geldi.
Bir milyona kadar asal sayıların oluşturulması, Benim istediğim zamandan çok daha fazla sürdü. Ancak 10 milyona kadar sayı öbeği oluşturmak imkansızdı. Program donuyordu.
Kendinizi benzer bir durumda bulursanız, farklı bir algoritma deneyebilirsiniz. Büyük sayılarda daha iyi çalışan arama ve sıralama algoritmaları vardır. Bu tür algoritmaların dezavantajı, anlaşılmasının zor olması olabilir. Diğer bir seçenek, farklı bir programlama dili kullanmaktır.
Derlenmiş bir dil, kodu daha hızlı işleyebilir. Ancak farklı bir dil kullanmak pratik olmayabilir. Ayrıca birden fazla iş parçacığı kullanmayı da deneyebilirsiniz. Bir kez daha, bu pratik olmayabilir çünkü programlama dilinizin onu desteklemesi gerekir.
Neyse ki, JavaScript ile başka bir seçenek daha var. Hesaplama açısından yoğun bir göreviniz varsa, biraz verimlilik elde etmek için yineleyiciler ve oluşturucular kullanabilirsiniz. Yineleyiciler, bazı JavaScript koleksiyonlarının bir özelliğidir.
Yineleyiciler, bir listedeki öğeleri birer birer, sanki bir su akışı gibi tüketmenize olanak sağlayarak verimlilik katar. Generator'ler, yürütmeyi duraklatabilen özel bir fonksiyon türüdür. Oluşturucu çağrısı, ilk etapta bir listede saklamak zorunda kalmadan, her seferinde bir yığın veri üretmenize olanak tanır.
- HTML
- CSS
- PHP
- JQUERY
- PHOTOSHOP
- JavaScript
- Web Dünyası
- Linux
- MİTHRİL FRAMEWORK
- Laravel
- Git
- React
- HTML LİNK(Bağlantı)EKLEME - LİNK VERME
- HTML YAZI VE RESİM ORTALAMA
- HTML RESME LİNK VERME
- HTML FORM OLUŞTURMA
- CSS YATAY MENÜ YAPIMI
- HTML RESİM EKLEME
- CSS (BOYUT) GENİŞLİK VE YÜKSEKLİK (Width-Height)
- HTML DİV ve SPAN NEDİR?
- HTML ARKAPLANA MÜZİK EKLEME
- KALİTE KAYBETMEDEN RESİMLERİ BÜYÜTME