Az Önhöz hasonló olvasók támogatják a MUO-t. Amikor a webhelyünkön található linkek használatával vásárol, társult jutalékot kaphatunk. Olvass tovább.

Az adatgyűjtések hagyományos hurkokat használó iterálása gyorsan nehézkessé és lassúvá válhat, különösen akkor, ha nagy mennyiségű adattal kell foglalkozni.

A JavaScript generátorok és iterátorok megoldást kínálnak a nagy adatgyűjtemények hatékony iterációjára. Segítségükkel vezérelheti az iterációs folyamatot, egyesével adhatja ki az értékeket, valamint szüneteltetheti és folytathatja az iterációs folyamatot.

Itt bemutatja a JavaScript-iterátor alapjait és belső tulajdonságait, valamint azt, hogyan hozhat létre iterátort manuálisan és generátor használatával.

JavaScript iterátorok

Az iterátor egy JavaScript objektum, amely megvalósítja az iterátor protokollt. Ezek az objektumok úgy teszik ezt, hogy a következő módszer. Ez a metódus egy objektumot ad vissza, amely megvalósítja a IteratorResult felület.

A IteratorResult Az interfész két tulajdonságot tartalmaz:

Kész és érték. A Kész tulajdonság egy logikai érték, amely visszatér hamis ha az iterátor elő tudja állítani a sorozatában a következő értéket ill igaz ha az iterátor befejezte a sorozatát.

A érték A property egy JavaScript érték, amelyet az iterátor a sorozata során ad vissza. Amikor egy iterátor befejezi a sorozatát (amikor Készigaz), ez a tulajdonság visszatér határozatlan.

Ahogy a neve is sugallja, az iterátorok lehetővé teszik a JavaScript objektumok, például tömbök vagy térképek „iterálását”. Ez a viselkedés az iterálható protokoll miatt lehetséges.

A JavaScriptben az iterálható protokoll szabványos módja az iterálható objektumok meghatározásának, például mert... of hurok.

Például:

const gyümölcsök = ["Banán", "Mangó", "Alma", "Szőlő"];

számára (const iterátor nak,-nek gyümölcsök) {
konzol.log (iterátor);
}

/*
Banán
Mangó
alma
Szőlő
*/

Ez a példa ismétlődik a gyümölcsök tömb segítségével a mert... of hurok. Minden iterációban naplózza az aktuális értéket a konzolon. Ez azért lehetséges, mert a tömbök iterálhatók.

Egyes JavaScript típusok, például tömbök, karakterláncok, Készletek és Térképek, beépített iterálhatóak, mert (vagy a prototípusláncukban feljebb lévő objektumok egyike) egy @@iterátor módszer.

Más típusok, például az objektumok, alapértelmezés szerint nem iterálhatók.

Például:

const iterObject = {
autók: ["Tesla", "BMW", "Toyota"],
állatokat: ["Macska", "Kutya", "Hörcsög"],
étel: ["hamburgerek", "Pizza", "Tészta"],
};

számára (const iterátor nak,-nek iterObject) {
konzol.log (iterátor);
}

// TypeError: az iterObject nem iterálható

Ez a példa bemutatja, mi történik, ha egy nem iterálható objektum felett próbál meg ismételni.

Egy objektum iterálhatóvá tétele

Ahhoz, hogy egy objektum iterálható legyen, meg kell valósítani a Szimbólum.iterátor módszer az objektumon. Az iterálhatóvá váláshoz ennek a metódusnak egy olyan objektumot kell visszaadnia, amely megvalósítja a IteratorResult felület.

A Szimbólum.iterátor szimbólum ugyanazt a célt szolgálja, mint @@iterátor és felcserélhetően használhatók a „specifikációban”, de a kódban nem @@iterátor nem érvényes JavaScript szintaxis.

Az alábbi kódblokkok példát adnak arra, hogyan lehet egy objektumot iterálhatóvá tenni a iterObject.

Először adjuk hozzá a Szimbólum.iterátor módszer arra iterObject segítségével egy funkciót nyilatkozat.

Például így:

iterObject[Szimbólum.iterator] = funkció () {
// A következő kódblokkok ide kerülnek...
}

Ezután hozzá kell férnie az iterálhatóvá tenni kívánt objektum összes kulcsához. A gombokat a gombbal érheti el Object.keys metódus, amely egy objektum felsorolható tulajdonságainak tömbjét adja vissza. Egy tömb visszaadásához iterObject’s kulcsokat, adja át a ez kulcsszó érvként Object.keys.

Például:

hagyja objProperties = Tárgy.kulcsok(ez)

A tömbhöz való hozzáférés lehetővé teszi az objektum iterációs viselkedésének meghatározását.

Ezután nyomon kell követnie az objektum iterációit. Ezt számlálóváltozók segítségével érheti el.

Például:

hagyja propertyIndex = 0;
hagyja gyermekIndex = 0;

Az első számlálóváltozót az objektum tulajdonságainak, a másodikat pedig a tulajdonság gyermekeinek nyomon követésére fogja használni.

Ezután végre kell hajtania és vissza kell küldenie a következő módszer.

Például így:

Visszatérés {
következő() {
// A következő kódblokkok ide kerülnek...
}
}

Benne következő metódust, akkor kezelnie kell egy élesetet, amely akkor fordul elő, amikor a teljes objektum ismétlődik. Az éles eset kezeléséhez vissza kell adnia egy objektumot a érték állítva határozatlan és Kész állítva igaz.

Ha ezt az esetet nem kezeljük, az objektum feletti iteráció végtelen ciklust eredményez.

A következőképpen kezelheti az éles esetet:

ha (propertyIndex > objTulajdonságok.hossz- 1) {
Visszatérés {
érték: határozatlan,
Kész: igaz,
};
}

Ezután a korábban deklarált számlálóváltozókkal kell hozzáférnie az objektum tulajdonságaihoz és gyermekelemeihez.

Például így:

// Szülői és gyermektulajdonságok elérése
const tulajdonságok = ez[objProperties[propertyIndex]];

const property = tulajdonságok[childIndex];

Ezután meg kell valósítania néhány logikát a számlálóváltozók növeléséhez. A logikának vissza kell állítania a gyermekIndex amikor már nincs több elem egy tulajdonság tömbjében, és az objektum következő tulajdonságára lép. Ezenkívül növelnie kell gyermekIndex, ha még vannak elemek az aktuális tulajdonság tömbjében.

Például:

// Indexnövelő logika
if (childIndex >= property.length - 1) {
// ha nincs több elem a gyermektömbben
// Visszaállításgyermekindex
gyermekIndex = 0;

// Ugrás a következő tulajdonságra
propertyIndex++;
} más {
// Ugrás a következő elemre a gyermektömbben
gyermekIndex++
}

Végül adjon vissza egy objektumot a Kész tulajdonság beállítva hamis és a érték tulajdonság az iteráció aktuális gyermekelemére van állítva.

Például:

Visszatérés {
Kész: hamis,
érték: ingatlan,
};

Elkészült Szimbólum.iterátor A funkciónak hasonlónak kell lennie az alábbi kódblokkhoz:

iterObject[Szimbólum.iterator] = funkció () {
const objProperties = Tárgy.kulcsok(ez);
hagyja propertyIndex = 0;
hagyja gyermekIndex = 0;

Visszatérés {
következő: () => {
//Az éles eset kezelése
ha (propertyIndex > objTulajdonságok.hossz- 1) {
Visszatérés {
érték: határozatlan,
Kész: igaz,
};
}

// Szülői és gyermektulajdonságok elérése
const tulajdonságok = ez[objProperties[propertyIndex]];

const property = tulajdonságok[childIndex];

// Indexnövelő logika
if (childIndex >= property.length - 1) {
// ha nincs több elem a gyermektömbben
// Visszaállításgyermekindex
gyermekIndex = 0;

// Ugrás a következő tulajdonságra
propertyIndex++;
} más {
// Ugrás a következő elemre a gyermektömbben
gyermekIndex++
}

Visszatérés {
Kész: hamis,
érték: ingatlan,
};
},
};
};

Futás a mert... of hurok be iterObject ezt követően a megvalósítás után nem ad hibát, mivel megvalósítja a Szimbólum.iterátor módszer.

Az iterátorok manuális implementálása, ahogyan azt fent tettük, nem ajánlott, mivel nagyon hibás, és a logika nehezen kezelhető.

JavaScript generátorok

A JavaScript-generátor egy olyan függvény, amelynek végrehajtását bármikor szüneteltetheti és folytathatja. Ez a viselkedés lehetővé teszi, hogy idővel értéksorozatot állítson elő.

A generátor függvény, amely egy generátort ad vissza, alternatívát kínál az iterátorok létrehozására.

Létrehozhat generátorfüggvényt ugyanúgy, mint a JavaScriptben egy függvénydeklarációt. Az egyetlen különbség az, hogy hozzá kell fűzni egy csillagot (*) a függvény kulcsszóhoz.

Például:

funkció* példa () {
Visszatérés"Generátor"
}

Ha normál függvényt hív meg JavaScriptben, az a függvénye által megadott értéket adja vissza Visszatérés kulcsszó ill határozatlan másképp. De egy generátorfüggvény nem ad vissza azonnal semmilyen értéket. Egy Generator objektumot ad vissza, amelyet hozzárendelhet egy változóhoz.

Az iterátor aktuális értékének eléréséhez hívja a következő metódus a Generator objektumon.

Például:

const gen = példa();

console.log (gen.next()); // { érték: 'Generátor', Kész: igaz }

A fenti példában a érték ingatlan származott a Visszatérés kulcsszó, gyakorlatilag leállítja a generátort. Ez a viselkedés általában nem kívánatos a generátorfüggvényeknél, mivel az különbözteti meg őket a normál funkcióktól, hogy szüneteltethetik és újraindíthatják a végrehajtást.

A hozam kulcsszó

A hozam A kulcsszó lehetőséget biztosít a generátorokban lévő értékek iterálására azáltal, hogy szünetelteti a generátor függvény végrehajtását, és visszaadja az azt követő értéket.

Például:

funkció* példa() {
hozam"S modell"
hozam"X modell"
hozam"Kiber teherautó"

Visszatérés"Tesla"
}

const gen = példa();

console.log (gen.next()); // { érték: "S modell", Kész: hamis }

A fenti példában, amikor a következő metódus meghívásra kerül a példa generátor, minden alkalommal szünetel, amikor találkozik a hozam kulcsszó. A Kész ingatlanra is be lesz állítva hamis amíg nem találkozik a Visszatérés kulcsszó.

Hívja a következő módszer többször is a példa generátort ennek demonstrálására, akkor a következő kimenet lesz.

console.log (gen.next()); // { érték: "X modell", Kész: hamis }
console.log (gen.next()); // { érték: "Kiber teherautó", Kész: hamis }
console.log (gen.next()); // { érték: "Tesla", Kész: igaz }

konzol.log (gen.next()); // { érték: undefined, done: true }

A Generator objektumon keresztül is iterálhat a mert... of hurok.

Például:

számára (const iterátor nak,-nek gen) {
konzol.log (iterátor);
}

/*
S modell
X modell
Kiber teherautó
*/

Iterátorok és generátorok használata

Bár az iterátorok és generátorok absztrakt fogalmaknak tűnhetnek, nem azok. Hasznosak lehetnek végtelen adatfolyamokkal és adatgyűjteményekkel végzett munka során. Használhatja őket egyedi azonosítók létrehozására is. Az állapotkezelési könyvtárak, például a MobX-State-Tree (MST) szintén ezeket használják a motorháztető alatt.