Məzmuna keçin
  • Kateqoriyalar
  • Ən yeni
  • Teqlər
  • Populyar
Yığmaq
Brend loqosu
  1. Əsas səhifə
  2. Front-end
  3. JavaScript
  4. JavaScript-də Iterators və Generators

JavaScript-də Iterators və Generators

Planlaşdırılıb Sabitlənib Kilidlənib Köçürülüb JavaScript
iteratorsfunctionsgeneratorssymbol
2 Yazı 1 Yazarlar 54 Baxış
  • Ən köhnədən yeniyə
  • Ən yenidən köhnəyə
  • Ən çox səs
Cavab ver
  • Mövzu olaraq cavablandır
🔑 Daxil ol
Bu mövzu silindi. Yalnız mövzu idarəçiliyi imtiyazlarına malik olan istifadəçilər onu görə bilər.
  • codexC Oflayn
    codexC Oflayn
    codex
    üzərində yazmışdı sonuncu dəfə tərəfindən redaktə edilib
    #1

    JavaScript-də iterators və generators, məlumatların ardıcıl emalını daha çevik və oxunaqlı şəkildə idarə etməyə imkan verir. Bu anlayışlar ES6 (ECMAScript 2015) ilə JavaScript dilinə əlavə edilib və xüsusilə custom iterable strukturların yaradılmasında, lazy evaluation və asinxron proqramlaşdırma sahələrində böyük əhəmiyyət daşıyır.


    1. Iteration Protocols (İterasiya Protokolları)

    JavaScript-də iterasiya aşağıdakı iki əsas protokol üzərindən qurulur:

    1.1 Iterable protokolu

    Bu protokol, obyektin Symbol.iterator adlı xüsusi bir metodu vasitəsilə iterasiya edilə biləcəyini göstərir. Bu metod geriyə bir iterator obyekt qaytarmalıdır.

    1.2 Iterator protokolu

    Iterator obyektində next() metodu mövcud olur. Bu metod hər çağırıldıqda obyektin növbəti dəyərini və iterasiyanın bitib-bitmədiyini bildirən { value, done } şəklində obyekt qaytarır.


    String üzərində iterator istifadə

    const text = "Rhyme";
    const it  = text[Symbol.iterator]();
    
    console.log(it.next()); // { value: 'R', done: false }
    

    Array elementlərini iterator ilə çap edilməsi

    const cities = ["Sofia", "New Delhi", "Tokyo"];
    const iterableCities = cities[Symbol.iterator]();
    
    let result = iterableCities.next();
    while (!result.done) {
        console.log(result.value);
        result = iterableCities.next();
    }
    

    Öz Iteratorumuzu yaratmaq

    class Polygon {
        constructor(...sides) {
            this.sides = sides;
        }
    
        [Symbol.iterator]() {
            let index = 0;
            return {
                next: () => {
                    if (index < this.sides.length){
                        return { value: this.sides[index++], done: false }
                    }
                    return { done: true }
                }
            };
        }
    }
    
    const poly = new Polygon(1, 2, 3, 4, 5);
    for (let side of poly) {
        console.log(side);
    }
    

    2 Generators ilə tanışlıq

    Generatorlar function* sintaksisi ilə yaradılır. Onlar yield açar sözü ilə bir-bir dəyərlər qaytarır.

    function* generator() {
        yield 1;
        yield 2;
        yield 3;
    }
    
    const gen = generator();
    console.log(gen.next().value); // 1
    console.log(gen.next().value); // 2
    

    Class daxilində generator

    class Polygon {
        constructor(...sides) {
            this.sides = sides;
        }
    
        *[Symbol.iterator]() {
           for (const side of this.sides) {
             yield side;
           }
        }
    }
    

    ID Generatoru

    function* idMaker() {
        let id = 0;
        while (true) {
            yield id++;
        }
    }
    
    const it = idMaker();
    console.log(it.next().value); // 0
    console.log(it.next().value); // 1
    

    Parametr ötürmək

    function* observerGenerator() {
        console.log('Generator created');
        while (true) {
            const value = yield;
            console.log(`Value passed: ${value}`);
        }
    }
    
    const it = observerGenerator();
    it.next(); // Başlamaq üçün ilk çağırış
    it.next(42); // Console: Value passed: 42
    

    yield* ilə generatorlar içində generator

    function* citiesGenerator() {
        yield 'Paris';
        yield* ['Rome', 'Florence', 'Berlin'];
    }
    
    const it = citiesGenerator();
    for (const city of it) {
        console.log(city);
    }
    

    Özünü yoxlmaq üçün mövzu üzrə tapşırıqlar

    Misal 1: Sadə ədədləri verən generator funksiyası yazın

    Bu məşqdə məqsəd, sadə ədədləri (prime numbers) ardıcıl olaraq verə bilən bir generator funksiyası yazmaqdır. Sadə ədədlər yalnız 1 və özündən başqa heç bir ədədə bölünməyən ədədlərdir (məsələn: 2, 3, 5, 7, 11, 13 və s.).

    Yardımçı funksiya: isPrime(num)

    const isPrime = num => {
        for (let i = 2; i < num; i++) {
            if (num % i === 0) {
                return false;
            }
        }
        return num > 1;
    };
    

    const isPrime = num => {
        for (let i = 2; i < num; i++) {
            if (num % i === 0) return false;
        }
        return num > 1;
    }
    
    function* primeNumbersGenerator() {
        let num = 2;
        while (true) {
            if (isPrime(num)) yield num;
            num++;
        }
    }
    
    const primes = primeNumbersGenerator();
    console.log(primes.next().value); // 2
    console.log(primes.next().value); // 3
    console.log(primes.next().value); // 5
    

    Misal 2: Generator ilə sual-cavab prosesi

    Bu məşqdə bir generator funksiyası yaradaraq, onun necə sual verə biləcəyini və sonradan həmin suala verilən cavabı next() metodu ilə qəbul edərək qiymətləndirəcəyini öyrənəcəyik. solveRiddle adlı generator bizə bir sual qaytarmalı (misal: What’s the Answer to the Ultimate Question of Life, the Universe, and Everything?) sonra daxil olan cavaba uyğun olaraq novbəti çağırışda true və ya false qaytarmalıdır. Misal üçün 42 yazılıbsa true.

    function* solveRiddle() {
        const question = "What's the Answer to the Ultimate Question of Life, the Universe, and Everything?";
        const answer = yield question;
        yield answer === 42;
    }
    
    const it = solveRiddle();
    console.log(it.next().value); // sualı qaytarır
    console.log(it.next(42).value); // true
    

    Misal 3: Massivin Flatten olunması (Yastılanması)

    Bu məşqdə məqsəd nested array-ləri (yəni iç-içə massivləri) istədiyimiz qədər dərinlikdə “yastılaşdırmaqdır” – yəni içərisindəki bütün elementləri tək səviyyəli array halına salmaqdır. flatten adlı bir generator function yazılmalıdır ki, o daxil olan array-in içərisindəki elementləri yield etməklə tək-tək qaytarsın. Əgər element array-dirsə və depth > 0-dırsa, həmin elementi yenidən flatten funksiyası ilə rekursiv şəkildə açmaq lazımdır (yield* istifadə etməklə).

    function* flatten(array, depth = 1) {
        for (const item of array) {
            if (Array.isArray(item) && depth > 0) {
                yield* flatten(item, depth - 1);
            } else {
                yield item;
            }
        }
    }
    
    const arr = [1, 2, [3, 4, [5, 6]]];
    const flattened = [...flatten(arr, Infinity)];
    console.log(flattened); // [1, 2, 3, 4, 5, 6]
    


    Nəticə

    JavaScript-də Iterators və Generators mövzusu, inkişaf etmiş iterasiya strukturları və performanslı həllər yaratmaq üçün güclü vasitələr təklif edir. Onlar həm custom data structures, həm də lazy evaluation, stream processing, və asinxron əməliyyatlar üçün vacibdir.

    1 cavab Son cavab
    • codexC Oflayn
      codexC Oflayn
      codex
      üzərində yazmışdı sonuncu dəfə tərəfindən redaktə edilib
      #2
      function* observerGenerator() {
          while (true) {
              console.log(`Value passed: ${yield}`);
          }
      }
      
      const obs = observerGenerator();
      obs.next('first');
      obs.next('second');
      obs.next('third');
      

      Gəlin bu generator funksiyasının necə işlədiyini addım-addım izah edək ki, niyə yalnız "second" və "third" dəyərləri ekrana çıxır, anlaşılsın.


      Addım-addım izah:

      ✅ Addım 1: Generator yaradılır

      const obs = observerGenerator();
      

      Bu sətir observerGenerator generator funksiyasını başlatmır, sadəcə obs adlı generator obyektini yaradır.


      ✅ Addım 2: obs.next('first')

      Generator ilk dəfə next('first') ilə işə salınır.

      obs.next('first');
      

      Vacib məqam: Generatorlar yield sətrinə çatana qədər kodu işlətməyə başlayır. Bizim generatorda ilk sətir bu olur:

      console.log(`Value passed: ${yield}`);
      

      Burada yield ifadəsi özündə dəyəri saxlayır, amma ilk dəfə next() çağırıldıqda, yield-ə verilən dəyər gözlənilmir, çünki generator hələ dayanmamışdı.

      • Yəni obs.next('first') çağırıldıqda:
        • Generator işə düşür,
        • yield-ə gəlib dayanır,
        • Amma yield-ə dəyər ötürülmür, ona görə də console.log(...) işləmir.

      ✅ Addım 3: obs.next('second')

      İndi isə yield artıq dayandığı yerdə gözləyir. Biz second dəyərini ötürürük:

      obs.next('second');
      
      • Bu dəyər birbaşa yield ifadəsinə ötürülür
      • console.log(...) artıq işləyir və:
        Value passed: second
        

      ✅ Addım 4: obs.next('third')

      Bu dəfə eyni proses təkrar olunur:

      obs.next('third');
      
      • third dəyəri yenə yield-ə ötürülür,
      • console.log(...) işləyir:
        Value passed: third
        

      Nəticə:

      Yalnız ikinci və üçüncü next() çağırışlarında console.log() işləyir, çünki:

      • İlk next() generatoru yield-ə qədər aparır və heç bir dəyər ötürmür (sadəcə start verir).
      • Sonrakı next(dəyər) çağırışları isə yield-ə dəyər ötürür və nəticədə console.log() işləyir.

      Qısa xülasə:

      next() çağırışı yield-ə nə ötürülür? Nəticə
      obs.next('first') Heç nə console.log() işləmir
      obs.next('second') 'second' Çıxış: Value passed: second
      obs.next('third') 'third' Çıxış: Value passed: third
      1 cavab Son cavab
      Cavab ver
      • Mövzu olaraq cavablandır
      🔑 Daxil ol
      • Ən köhnədən yeniyə
      • Ən yenidən köhnəyə
      • Ən çox səs




      Bilik paylaşdıqca artan bir sərvətdir
      • Daxil ol

      • Sizin hesabınız yoxdur? Qeydiyyatdan keç

      • Axtarış etmək üçün daxil olun və ya qeydiyyatdan keçin.
      • İlk yazı
        Son yazı
      0
      • Kateqoriyalar
      • Ən yeni
      • Teqlər
      • Populyar