Prozkoumejte pomocníky pro asynchronní iterátory v JavaScriptu pro revoluční zpracování streamů. Naučte se efektivně pracovat s datovými proudy pomocí map, filter, take, drop a dalších.
Pomocníci pro asynchronní iterátory v JavaScriptu: Výkonné zpracování streamů pro moderní aplikace
V moderním vývoji v JavaScriptu je práce s asynchronními datovými proudy běžným požadavkem. Ať už načítáte data z API, zpracováváte velké soubory nebo obsluhujete události v reálném čase, efektivní správa asynchronních dat je klíčová. Pomocníci pro asynchronní iterátory v JavaScriptu poskytují výkonný a elegantní způsob, jak tyto proudy zpracovávat, a nabízejí funkcionální a skládatelný přístup k manipulaci s daty.
Co jsou asynchronní iterátory a asynchronní iterovatelné objekty?
Než se ponoříme do pomocníků pro asynchronní iterátory, pojďme si vysvětlit základní koncepty: asynchronní iterátory a asynchronní iterovatelné objekty.
Asynchronní iterovatelný objekt (Async Iterable) je objekt, který definuje způsob, jak asynchronně procházet jeho hodnoty. Dělá to implementací metody @@asyncIterator
, která vrací asynchronní iterátor (Async Iterator).
Asynchronní iterátor (Async Iterator) je objekt, který poskytuje metodu next()
. Tato metoda vrací promise, která se resolvuje na objekt se dvěma vlastnostmi:
value
: Další hodnota v sekvenci.done
: Booleovská hodnota udávající, zda byla sekvence plně spotřebována.
Zde je jednoduchý příklad:
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Simulace asynchronní operace
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
for await (const value of asyncIterable) {
console.log(value); // Výstup: 1, 2, 3, 4, 5 (s 500ms zpožděním mezi každým)
}
})();
V tomto příkladu je generateSequence
asynchronní generátorová funkce, která asynchronně vytváří sekvenci čísel. Smyčka for await...of
se používá ke spotřebování hodnot z asynchronního iterovatelného objektu.
Představení pomocníků pro asynchronní iterátory
Pomocníci pro asynchronní iterátory rozšiřují funkcionalitu asynchronních iterátorů a poskytují sadu metod pro transformaci, filtrování a manipulaci s asynchronními datovými proudy. Umožňují funkcionální a skládatelný styl programování, což usnadňuje tvorbu složitých pipeline pro zpracování dat.
Mezi hlavní pomocníky pro asynchronní iterátory patří:
map()
: Transformuje každý prvek streamu.filter()
: Vybírá prvky ze streamu na základě podmínky.take()
: Vrací prvních N prvků streamu.drop()
: Přeskočí prvních N prvků streamu.toArray()
: Shromáždí všechny prvky streamu do pole.forEach()
: Provede poskytnutou funkci jednou pro každý prvek streamu.some()
: Zkontroluje, zda alespoň jeden prvek splňuje zadanou podmínku.every()
: Zkontroluje, zda všechny prvky splňují zadanou podmínku.find()
: Vrací první prvek, který splňuje zadanou podmínku.reduce()
: Aplikuje funkci na akumulátor a každý prvek, aby jej zredukovala na jednu hodnotu.
Pojďme se podívat na každého pomocníka s příklady.
map()
Pomocník map()
transformuje každý prvek asynchronního iterovatelného objektu pomocí zadané funkce. Vrací nový asynchronní iterovatelný objekt s transformovanými hodnotami.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
const doubledIterable = asyncIterable.map(x => x * 2);
(async () => {
for await (const value of doubledIterable) {
console.log(value); // Výstup: 2, 4, 6, 8, 10 (se 100ms zpožděním)
}
})();
V tomto příkladu map(x => x * 2)
zdvojnásobí každé číslo v sekvenci.
filter()
Pomocník filter()
vybírá prvky z asynchronního iterovatelného objektu na základě zadané podmínky (predikátové funkce). Vrací nový asynchronní iterovatelný objekt obsahující pouze prvky, které splňují podmínku.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(10);
const evenNumbersIterable = asyncIterable.filter(x => x % 2 === 0);
(async () => {
for await (const value of evenNumbersIterable) {
console.log(value); // Výstup: 2, 4, 6, 8, 10 (se 100ms zpožděním)
}
})();
V tomto příkladu filter(x => x % 2 === 0)
vybere pouze sudá čísla ze sekvence.
take()
Pomocník take()
vrací prvních N prvků z asynchronního iterovatelného objektu. Vrací nový asynchronní iterovatelný objekt obsahující pouze zadaný počet prvků.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
const firstThreeIterable = asyncIterable.take(3);
(async () => {
for await (const value of firstThreeIterable) {
console.log(value); // Výstup: 1, 2, 3 (se 100ms zpožděním)
}
})();
V tomto příkladu take(3)
vybere první tři čísla ze sekvence.
drop()
Pomocník drop()
přeskočí prvních N prvků z asynchronního iterovatelného objektu a vrátí zbytek. Vrací nový asynchronní iterovatelný objekt obsahující zbývající prvky.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
const afterFirstTwoIterable = asyncIterable.drop(2);
(async () => {
for await (const value of afterFirstTwoIterable) {
console.log(value); // Výstup: 3, 4, 5 (se 100ms zpožděním)
}
})();
V tomto příkladu drop(2)
přeskočí první dvě čísla ze sekvence.
toArray()
Pomocník toArray()
spotřebuje celý asynchronní iterovatelný objekt a shromáždí všechny prvky do pole. Vrací promise, která se resolvuje na pole obsahující všechny prvky.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
const numbersArray = await asyncIterable.toArray();
console.log(numbersArray); // Výstup: [1, 2, 3, 4, 5]
})();
V tomto příkladu toArray()
shromáždí všechna čísla ze sekvence do pole.
forEach()
Pomocník forEach()
provede zadanou funkci jednou pro každý prvek v asynchronním iterovatelném objektu. Nevrací nový asynchronní iterovatelný objekt, provádí funkci s vedlejšími účinky. To může být užitečné pro provádění operací, jako je logování nebo aktualizace UI.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(3);
(async () => {
await asyncIterable.forEach(value => {
console.log("Hodnota:", value);
});
console.log("forEach dokončeno");
})();
// Výstup: Hodnota: 1, Hodnota: 2, Hodnota: 3, forEach dokončeno
some()
Pomocník some()
testuje, zda alespoň jeden prvek v asynchronním iterovatelném objektu projde testem implementovaným zadanou funkcí. Vrací promise, která se resolvuje na booleovskou hodnotu (true
, pokud alespoň jeden prvek splňuje podmínku, jinak false
).
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
const hasEvenNumber = await asyncIterable.some(x => x % 2 === 0);
console.log("Obsahuje sudé číslo:", hasEvenNumber); // Výstup: Obsahuje sudé číslo: true
})();
every()
Pomocník every()
testuje, zda všechny prvky v asynchronním iterovatelném objektu projdou testem implementovaným zadanou funkcí. Vrací promise, která se resolvuje na booleovskou hodnotu (true
, pokud všechny prvky splňují podmínku, jinak false
).
async function* generateSequence(end) {
for (let i = 2; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(4);
(async () => {
const areAllEven = await asyncIterable.every(x => x % 2 === 0);
console.log("Jsou všechna sudá:", areAllEven); // Výstup: Jsou všechna sudá: true
})();
find()
Pomocník find()
vrací první prvek v asynchronním iterovatelném objektu, který splňuje zadanou testovací funkci. Pokud žádná hodnota nesplňuje testovací funkci, je vráceno undefined
. Vrací promise, která se resolvuje na nalezený prvek nebo undefined
.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
const firstEven = await asyncIterable.find(x => x % 2 === 0);
console.log("První sudé číslo:", firstEven); // Výstup: První sudé číslo: 2
})();
reduce()
Pomocník reduce()
provádí uživatelem zadanou „reducer“ callback funkci na každém prvku asynchronního iterovatelného objektu v pořadí, přičemž předává návratovou hodnotu z výpočtu na předchozím prvku. Konečným výsledkem spuštění reduceru na všech prvcích je jedna hodnota. Vrací promise, která se resolvuje na konečnou akumulovanou hodnotu.
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
const sum = await asyncIterable.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log("Součet:", sum); // Výstup: Součet: 15
})();
Praktické příklady a případy použití
Pomocníci pro asynchronní iterátory jsou cenní v různých scénářích. Podívejme se na několik praktických příkladů:
1. Zpracování dat ze streamovacího API
Představte si, že vytváříte dashboard pro vizualizaci dat v reálném čase, který přijímá data ze streamovacího API. API posílá aktualizace nepřetržitě a vy je potřebujete zpracovat, abyste zobrazili nejnovější informace.
async function* fetchDataFromAPI(url) {
let response = await fetch(url);
if (!response.body) {
throw new Error("ReadableStream není v tomto prostředí podporován");
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
const chunk = decoder.decode(value);
// Za předpokladu, že API posílá JSON objekty oddělené novými řádky
const lines = chunk.split('\n');
for (const line of lines) {
if (line.trim() !== '') {
yield JSON.parse(line);
}
}
}
} finally {
reader.releaseLock();
}
}
const apiURL = 'https://example.com/streaming-api'; // Nahraďte vaší URL adresou API
const dataStream = fetchDataFromAPI(apiURL);
// Zpracování datového proudu
(async () => {
for await (const data of dataStream.filter(item => item.type === 'metric').map(item => ({ timestamp: item.timestamp, value: item.value }))) {
console.log('Zpracovaná data:', data);
// Aktualizace dashboardu zpracovanými daty
}
})();
V tomto příkladu fetchDataFromAPI
načítá data ze streamovacího API, parsuje JSON objekty a vrací je jako asynchronní iterovatelný objekt. Pomocník filter
vybere pouze metriky a pomocník map
transformuje data do požadovaného formátu před aktualizací dashboardu.
2. Čtení a zpracování velkých souborů
Předpokládejme, že potřebujete zpracovat velký CSV soubor obsahující zákaznická data. Místo načítání celého souboru do paměti můžete použít pomocníky pro asynchronní iterátory ke zpracování po částech.
async function* readLinesFromFile(filePath) {
const file = await fsPromises.open(filePath, 'r');
try {
let buffer = Buffer.alloc(1024);
let fileOffset = 0;
let remainder = '';
while (true) {
const { bytesRead } = await file.read(buffer, 0, buffer.length, fileOffset);
if (bytesRead === 0) {
if (remainder) {
yield remainder;
}
break;
}
fileOffset += bytesRead;
const chunk = buffer.toString('utf8', 0, bytesRead);
const lines = chunk.split('\n');
lines[0] = remainder + lines[0];
remainder = lines.pop() || '';
for (const line of lines) {
yield line;
}
}
} finally {
await file.close();
}
}
const filePath = './customer_data.csv'; // Nahraďte cestou k vašemu souboru
const lines = readLinesFromFile(filePath);
// Zpracování řádků
(async () => {
for await (const customerData of lines.drop(1).map(line => line.split(',')).filter(data => data[2] === 'USA')) {
console.log('Zákazník z USA:', customerData);
// Zpracování dat zákazníků z USA
}
})();
V tomto příkladu readLinesFromFile
čte soubor řádek po řádku a vrací každý řádek jako asynchronní iterovatelný objekt. Pomocník drop(1)
přeskočí hlavičkový řádek, pomocník map
rozdělí řádek na sloupce a pomocník filter
vybere pouze zákazníky z USA.
3. Zpracování událostí v reálném čase
Pomocníci pro asynchronní iterátory mohou být také použiti ke zpracování událostí v reálném čase ze zdrojů, jako jsou WebSockets. Můžete vytvořit asynchronní iterovatelný objekt, který emituje události, jakmile přijdou, a poté použít pomocníky k jejich zpracování.
async function* createWebSocketStream(url) {
const ws = new WebSocket(url);
yield new Promise((resolve, reject) => {
ws.onopen = () => {
resolve();
};
ws.onerror = (error) => {
reject(error);
};
});
try {
while (ws.readyState === WebSocket.OPEN) {
yield new Promise((resolve, reject) => {
ws.onmessage = (event) => {
resolve(JSON.parse(event.data));
};
ws.onerror = (error) => {
reject(error);
};
ws.onclose = () => {
resolve(null); // Resolve s hodnotou null při uzavření spojení
}
});
}
} finally {
ws.close();
}
}
const websocketURL = 'wss://example.com/events'; // Nahraďte vaší WebSocket URL
const eventStream = createWebSocketStream(websocketURL);
// Zpracování proudu událostí
(async () => {
for await (const event of eventStream.filter(event => event.type === 'user_login').map(event => ({ userId: event.userId, timestamp: event.timestamp }))) {
console.log('Událost přihlášení uživatele:', event);
// Zpracování události přihlášení uživatele
}
})();
V tomto příkladu createWebSocketStream
vytváří asynchronní iterovatelný objekt, který emituje události přijaté z WebSocketu. Pomocník filter
vybere pouze události přihlášení uživatele a pomocník map
transformuje data do požadovaného formátu.
Výhody používání pomocníků pro asynchronní iterátory
- Zlepšená čitelnost a udržovatelnost kódu: Pomocníci pro asynchronní iterátory podporují funkcionální a skládatelný styl programování, což usnadňuje čtení, porozumění a údržbu vašeho kódu. Řetězitelná povaha pomocníků vám umožňuje vyjádřit složité pipeline pro zpracování dat stručným a deklarativním způsobem.
- Efektivní využití paměti: Pomocníci pro asynchronní iterátory zpracovávají datové proudy líně (lazily), což znamená, že zpracovávají data pouze podle potřeby. To může výrazně snížit spotřebu paměti, zejména při práci s velkými datovými sadami nebo nepřetržitými datovými proudy.
- Zvýšený výkon: Zpracováním dat ve streamu mohou pomocníci pro asynchronní iterátory zlepšit výkon tím, že se vyhnou nutnosti načítat celou datovou sadu do paměti najednou. To může být zvláště výhodné pro aplikace, které zpracovávají velké soubory, data v reálném čase nebo streamovací API.
- Zjednodušené asynchronní programování: Pomocníci pro asynchronní iterátory abstrahují složitosti asynchronního programování, což usnadňuje práci s asynchronními datovými proudy. Nemusíte ručně spravovat promise nebo callbacky; pomocníci se o asynchronní operace postarají na pozadí.
- Skládatelný a znovupoužitelný kód: Pomocníci pro asynchronní iterátory jsou navrženi tak, aby byli skládatelní, což znamená, že je můžete snadno řetězit a vytvářet tak složité pipeline pro zpracování dat. To podporuje znovupoužití kódu a snižuje jeho duplicitu.
Podpora v prohlížečích a běhových prostředích
Pomocníci pro asynchronní iterátory jsou v JavaScriptu stále relativně novou funkcí. Ke konci roku 2024 jsou ve fázi 3 standardizačního procesu TC39, což znamená, že je pravděpodobné, že budou v blízké budoucnosti standardizováni. Zatím však nejsou nativně podporováni ve všech prohlížečích a verzích Node.js.
Podpora v prohlížečích: Moderní prohlížeče jako Chrome, Firefox, Safari a Edge postupně přidávají podporu pro pomocníky pro asynchronní iterátory. Nejnovější informace o kompatibilitě prohlížečů můžete zkontrolovat na webových stránkách jako Can I use..., abyste zjistili, které prohlížeče tuto funkci podporují.
Podpora v Node.js: Novější verze Node.js (v18 a vyšší) poskytují experimentální podporu pro pomocníky pro asynchronní iterátory. Abyste je mohli používat, možná budete muset spustit Node.js s příznakem --experimental-async-iterator
.
Polyfilly: Pokud potřebujete používat pomocníky pro asynchronní iterátory v prostředích, která je nativně nepodporují, můžete použít polyfill. Polyfill je kousek kódu, který poskytuje chybějící funkcionalitu. K dispozici je několik knihoven polyfillů pro pomocníky pro asynchronní iterátory; populární volbou je knihovna core-js
.
Implementace vlastních asynchronních iterátorů
I když pomocníci pro asynchronní iterátory poskytují pohodlný způsob zpracování existujících asynchronních iterovatelných objektů, někdy budete možná potřebovat vytvořit své vlastní. To vám umožní zpracovávat data z různých zdrojů, jako jsou databáze, API nebo souborové systémy, streamovacím způsobem.
Chcete-li vytvořit vlastní asynchronní iterátor, musíte na objektu implementovat metodu @@asyncIterator
. Tato metoda by měla vrátit objekt s metodou next()
. Metoda next()
by měla vrátit promise, která se resolvuje na objekt s vlastnostmi value
a done
.
Zde je příklad vlastního asynchronního iterátoru, který načítá data z paginovaného API:
async function* fetchPaginatedData(baseURL) {
let page = 1;
let hasMore = true;
while (hasMore) {
const url = `${baseURL}?page=${page}`;
const response = await fetch(url);
const data = await response.json();
if (data.results.length === 0) {
hasMore = false;
break;
}
for (const item of data.results) {
yield item;
}
page++;
}
}
const apiBaseURL = 'https://api.example.com/data'; // Nahraďte vaší URL adresou API
const paginatedData = fetchPaginatedData(apiBaseURL);
// Zpracování paginovaných dat
(async () => {
for await (const item of paginatedData) {
console.log('Položka:', item);
// Zpracování položky
}
})();
V tomto příkladu fetchPaginatedData
načítá data z paginovaného API a vrací každou položku, jakmile je načtena. Asynchronní iterátor se stará o logiku paginace, což usnadňuje konzumaci dat streamovacím způsobem.
Potenciální výzvy a úvahy
Ačkoli pomocníci pro asynchronní iterátory nabízejí řadu výhod, je důležité si být vědom některých potenciálních výzev a úvah:
- Zpracování chyb: Správné zpracování chyb je při práci s asynchronními datovými proudy klíčové. Musíte ošetřit potenciální chyby, které mohou nastat během načítání, zpracování nebo transformace dat. Použití bloků
try...catch
a technik pro zpracování chyb v rámci vašich pomocníků pro asynchronní iterátory je nezbytné. - Zrušení: V některých scénářích možná budete potřebovat zrušit zpracování asynchronního iterovatelného objektu dříve, než je plně spotřebován. To může být užitečné při práci s dlouhotrvajícími operacemi nebo datovými proudy v reálném čase, kde chcete zastavit zpracování po splnění určité podmínky. Implementace mechanismů pro zrušení, jako je použití
AbortController
, vám může pomoci efektivně spravovat asynchronní operace. - Zpětný tlak (Backpressure): Při práci s datovými proudy, které produkují data rychleji, než je lze spotřebovat, se stává problémem zpětný tlak. Zpětný tlak označuje schopnost spotřebitele signalizovat producentovi, aby zpomalil rychlost, jakou jsou data emitována. Implementace mechanismů zpětného tlaku může zabránit přetížení paměti a zajistit efektivní zpracování datového proudu.
- Ladění (Debugging): Ladění asynchronního kódu může být náročnější než ladění synchronního kódu. Při práci s pomocníky pro asynchronní iterátory je důležité používat ladicí nástroje a techniky k sledování toku dat skrze pipeline a identifikaci případných problémů.
Doporučené postupy pro používání pomocníků pro asynchronní iterátory
Abyste z pomocníků pro asynchronní iterátory vytěžili co nejvíce, zvažte následující doporučené postupy:
- Používejte popisné názvy proměnných: Vybírejte popisné názvy proměnných, které jasně naznačují účel každého asynchronního iterovatelného objektu a pomocníka. To usnadní čtení a pochopení vašeho kódu.
- Udržujte pomocné funkce stručné: Udržujte funkce předávané pomocníkům pro asynchronní iterátory co nejstručnější a nejzaměřenější. Vyhněte se provádění složitých operací v těchto funkcích; místo toho vytvořte samostatné funkce pro složitou logiku.
- Řetězte pomocníky pro čitelnost: Řetězte pomocníky pro asynchronní iterátory dohromady, abyste vytvořili jasnou a deklarativní pipeline pro zpracování dat. Vyhněte se nadměrnému vnořování pomocníků, protože to může ztížit čtení vašeho kódu.
- Zpracovávejte chyby elegantně: Implementujte správné mechanismy pro zpracování chyb, abyste zachytili a ošetřili potenciální chyby, které mohou nastat během zpracování dat. Poskytujte informativní chybové zprávy, které pomohou diagnostikovat a řešit problémy.
- Důkladně testujte svůj kód: Důkladně testujte svůj kód, abyste se ujistili, že správně zvládá různé scénáře. Pište jednotkové testy pro ověření chování jednotlivých pomocníků a integrační testy pro ověření celkové pipeline pro zpracování dat.
Pokročilé techniky
Skládání vlastních pomocníků
Můžete si vytvořit vlastní pomocníky pro asynchronní iterátory skládáním existujících pomocníků nebo jejich tvorbou od nuly. To vám umožní přizpůsobit funkcionalitu vašim specifickým potřebám a vytvářet znovupoužitelné komponenty.
async function* takeWhile(asyncIterable, predicate) {
for await (const value of asyncIterable) {
if (!predicate(value)) {
break;
}
yield value;
}
}
// Příklad použití:
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}
const asyncIterable = generateSequence(10);
const firstFive = takeWhile(asyncIterable, x => x <= 5);
(async () => {
for await (const value of firstFive) {
console.log(value);
}
})();
Kombinování více asynchronních iterovatelných objektů
Můžete zkombinovat více asynchronních iterovatelných objektů do jednoho pomocí technik jako zip
nebo merge
. To vám umožní zpracovávat data z více zdrojů současně.
async function* zip(asyncIterable1, asyncIterable2) {
const iterator1 = asyncIterable1[Symbol.asyncIterator]();
const iterator2 = asyncIterable2[Symbol.asyncIterator]();
while (true) {
const result1 = await iterator1.next();
const result2 = await iterator2.next();
if (result1.done || result2.done) {
break;
}
yield [result1.value, result2.value];
}
}
// Příklad použití:
async function* generateSequence1(end) {
for (let i = 1; i <= end; i++) {
yield i;
}
}
async function* generateSequence2(end) {
for (let i = 10; i <= end + 9; i++) {
yield i;
}
}
const iterable1 = generateSequence1(5);
const iterable2 = generateSequence2(5);
(async () => {
for await (const [value1, value2] of zip(iterable1, iterable2)) {
console.log(value1, value2);
}
})();
Závěr
Pomocníci pro asynchronní iterátory v JavaScriptu poskytují výkonný a elegantní způsob zpracování asynchronních datových proudů. Nabízejí funkcionální a skládatelný přístup k manipulaci s daty, což usnadňuje tvorbu složitých pipeline pro zpracování dat. Porozuměním základním konceptům asynchronních iterátorů a iterovatelných objektů a zvládnutím různých pomocných metod můžete výrazně zlepšit efektivitu a udržovatelnost vašeho asynchronního JavaScriptového kódu. S rostoucí podporou v prohlížečích a běhových prostředích jsou pomocníci pro asynchronní iterátory připraveni stát se nezbytným nástrojem pro moderní vývojáře v JavaScriptu.