Ismerje meg a JavaScript Async Iterator segédfüggvényeket az adatfolyam-feldolgozás forradalmasításához. Tanulja meg az aszinkron adatfolyamok hatékony kezelését a map, filter, take, drop és egyéb metódusokkal.
JavaScript Async Iterator segédfüggvények: Hatékony adatfolyam-feldolgozás modern alkalmazásokhoz
A modern JavaScript fejlesztésben gyakori követelmény az aszinkron adatfolyamok kezelése. Legyen szó API-ból történő adatlekérésről, nagy fájlok feldolgozásáról vagy valós idejű események kezeléséről, az aszinkron adatok hatékony kezelése kulcsfontosságú. A JavaScript Async Iterator segédfüggvényei erőteljes és elegáns módot kínálnak ezen adatfolyamok feldolgozására, funkcionális és kompozíciós megközelítést biztosítva az adatmanipulációhoz.
Mik azok az aszinkron iterátorok és aszinkron iterálható objektumok?
Mielőtt belemerülnénk az Async Iterator segédfüggvényekbe, értsük meg az alapul szolgáló koncepciókat: az aszinkron iterátorokat és az aszinkron iterálható objektumokat.
Az aszinkron iterálható objektum (Async Iterable) egy olyan objektum, amely meghatározza az értékein való aszinkron iterálás módját. Ezt a @@asyncIterator
metódus implementálásával teszi, amely egy aszinkron iterátort (Async Iterator) ad vissza.
Az aszinkron iterátor (Async Iterator) egy olyan objektum, amely rendelkezik egy next()
metódussal. Ez a metódus egy promise-t ad vissza, amely egy két tulajdonsággal rendelkező objektumra oldódik fel:
value
: A sorozat következő értéke.done
: Egy boolean érték, amely jelzi, hogy a sorozat teljesen feldolgozásra került-e.
Íme egy egyszerű példa:
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Aszinkron művelet szimulálása
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
for await (const value of asyncIterable) {
console.log(value); // Kimenet: 1, 2, 3, 4, 5 (mindegyik között 500ms késleltetéssel)
}
})();
Ebben a példában a generateSequence
egy aszinkron generátorfüggvény, amely aszinkron módon hoz létre egy számsorozatot. A for await...of
ciklus az aszinkron iterálható objektumból származó értékek feldolgozására szolgál.
Az Async Iterator segédfüggvények bemutatása
Az Async Iterator segédfüggvények kiterjesztik az aszinkron iterátorok funkcionalitását, egy sor metódust biztosítva az aszinkron adatfolyamok átalakítására, szűrésére és manipulálására. Lehetővé teszik a funkcionális és kompozíciós programozási stílust, megkönnyítve az összetett adatfeldolgozási láncok kiépítését.
A legfontosabb Async Iterator segédfüggvények a következők:
map()
: Átalakítja az adatfolyam minden elemét.filter()
: Feltétel alapján választ ki elemeket az adatfolyamból.take()
: Visszaadja az adatfolyam első N elemét.drop()
: Kihagyja az adatfolyam első N elemét.toArray()
: Az adatfolyam összes elemét egy tömbbe gyűjti.forEach()
: Minden adatfolyam-elemre egyszer végrehajt egy megadott függvényt.some()
: Ellenőrzi, hogy legalább egy elem megfelel-e a megadott feltételnek.every()
: Ellenőrzi, hogy minden elem megfelel-e a megadott feltételnek.find()
: Visszaadja az első elemet, amely megfelel a megadott feltételnek.reduce()
: Egy függvényt alkalmaz egy akkumulátorra és minden elemre, hogy egyetlen értékké redukálja őket.
Nézzük meg az egyes segédfüggvényeket példákkal.
map()
A map()
segédfüggvény egy megadott függvény segítségével átalakítja az aszinkron iterálható objektum minden elemét. Visszaad egy új, az átalakított értékeket tartalmazó aszinkron iterálható objektumot.
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); // Kimenet: 2, 4, 6, 8, 10 (100ms késleltetéssel)
}
})();
Ebben a példában a map(x => x * 2)
megduplázza a sorozat minden számát.
filter()
A filter()
segédfüggvény egy megadott feltétel (predikátumfüggvény) alapján választ ki elemeket az aszinkron iterálható objektumból. Visszaad egy új aszinkron iterálható objektumot, amely csak a feltételnek megfelelő elemeket tartalmazza.
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); // Kimenet: 2, 4, 6, 8, 10 (100ms késleltetéssel)
}
})();
Ebben a példában a filter(x => x % 2 === 0)
csak a páros számokat választja ki a sorozatból.
take()
A take()
segédfüggvény visszaadja az aszinkron iterálható objektum első N elemét. Egy új aszinkron iterálható objektumot ad vissza, amely csak a megadott számú elemet tartalmazza.
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); // Kimenet: 1, 2, 3 (100ms késleltetéssel)
}
})();
Ebben a példában a take(3)
a sorozat első három számát választja ki.
drop()
A drop()
segédfüggvény kihagyja az aszinkron iterálható objektum első N elemét, és a többit adja vissza. Egy új aszinkron iterálható objektumot ad vissza, amely a fennmaradó elemeket tartalmazza.
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); // Kimenet: 3, 4, 5 (100ms késleltetéssel)
}
})();
Ebben a példában a drop(2)
kihagyja a sorozat első két számát.
toArray()
A toArray()
segédfüggvény feldolgozza a teljes aszinkron iterálható objektumot, és az összes elemet egy tömbbe gyűjti. Visszaad egy promise-t, amely egy, az összes elemet tartalmazó tömbre oldódik fel.
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); // Kimenet: [1, 2, 3, 4, 5]
})();
Ebben a példában a toArray()
a sorozat összes számát egy tömbbe gyűjti.
forEach()
A forEach()
segédfüggvény minden elemre egyszer végrehajt egy megadott függvényt az aszinkron iterálható objektumban. *Nem* ad vissza új aszinkron iterálható objektumot, hanem mellékhatásként hajtja végre a függvényt. Ez hasznos lehet olyan műveletekhez, mint a naplózás vagy egy felhasználói felület frissítése.
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("Value:", value);
});
console.log("forEach completed");
})();
// Kimenet: Value: 1, Value: 2, Value: 3, forEach completed
some()
A some()
segédfüggvény azt teszteli, hogy az aszinkron iterálható objektumban legalább egy elem megfelel-e a megadott függvény által implementált tesztnek. Visszaad egy promise-t, amely egy logikai értékre oldódik fel (true
, ha legalább egy elem megfelel a feltételnek, egyébként 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("Has even number:", hasEvenNumber); // Kimenet: Has even number: true
})();
every()
Az every()
segédfüggvény azt teszteli, hogy az aszinkron iterálható objektum összes eleme megfelel-e a megadott függvény által implementált tesztnek. Visszaad egy promise-t, amely egy logikai értékre oldódik fel (true
, ha minden elem megfelel a feltételnek, egyébként 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("Are all even:", areAllEven); // Kimenet: Are all even: true
})();
find()
A find()
segédfüggvény visszaadja az aszinkron iterálható objektum első elemét, amely megfelel a megadott tesztelő függvénynek. Ha egyetlen érték sem felel meg a tesztelő függvénynek, undefined
értéket ad vissza. Visszaad egy promise-t, amely a talált elemre vagy undefined
-ra oldódik fel.
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("First even number:", firstEven); // Kimenet: First even number: 2
})();
reduce()
A reduce()
segédfüggvény egy felhasználó által megadott "reducer" visszahívási függvényt hajt végre az aszinkron iterálható objektum minden elemén sorrendben, átadva az előző elem számításából származó visszatérési értéket. A reducer összes elemen való futtatásának végeredménye egyetlen érték. Visszaad egy promise-t, amely a végső felhalmozott értékre oldódik fel.
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("Sum:", sum); // Kimenet: Sum: 15
})();
Gyakorlati példák és felhasználási esetek
Az Async Iterator segédfüggvények számos forgatókönyvben értékesek. Nézzünk meg néhány gyakorlati példát:
1. Adatok feldolgozása streaming API-ból
Képzelje el, hogy egy valós idejű adatvizualizációs műszerfalat épít, amely egy streaming API-ból kap adatokat. Az API folyamatosan küld frissítéseket, és ezeket fel kell dolgoznia a legfrissebb információk megjelenítéséhez.
async function* fetchDataFromAPI(url) {
let response = await fetch(url);
if (!response.body) {
throw new Error("ReadableStream not supported in this environment");
}
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);
// Feltételezve, hogy az API újsorokkal elválasztott JSON objektumokat küld
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'; // Cserélje le a saját API URL-jére
const dataStream = fetchDataFromAPI(apiURL);
// Az adatfolyam feldolgozása
(async () => {
for await (const data of dataStream.filter(item => item.type === 'metric').map(item => ({ timestamp: item.timestamp, value: item.value }))) {
console.log('Feldolgozott adat:', data);
// A műszerfal frissítése a feldolgozott adatokkal
}
})();
Ebben a példában a fetchDataFromAPI
adatokat kér le egy streaming API-ból, elemzi a JSON objektumokat, és aszinkron iterálható objektumként adja vissza őket. A filter
segédfüggvény csak a metrikákat választja ki, a map
segédfüggvény pedig a kívánt formátumra alakítja az adatokat a műszerfal frissítése előtt.
2. Nagy fájlok olvasása és feldolgozása
Tegyük fel, hogy egy nagy, ügyféladatokat tartalmazó CSV-fájlt kell feldolgoznia. Ahelyett, hogy a teljes fájlt a memóriába töltené, az Async Iterator segédfüggvényekkel darabonként dolgozhatja fel.
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'; // Cserélje le a saját fájlútvonalára
const lines = readLinesFromFile(filePath);
// A sorok feldolgozása
(async () => {
for await (const customerData of lines.drop(1).map(line => line.split(',')).filter(data => data[2] === 'USA')) {
console.log('Amerikai ügyfél:', customerData);
// Az amerikai ügyféladatok feldolgozása
}
})();
Ebben a példában a readLinesFromFile
soronként olvassa a fájlt, és minden sort aszinkron iterálható objektumként ad vissza. A drop(1)
segédfüggvény kihagyja a fejléc sort, a map
segédfüggvény oszlopokra bontja a sort, a filter
segédfüggvény pedig csak az amerikai ügyfeleket választja ki.
3. Valós idejű események kezelése
Az Async Iterator segédfüggvények valós idejű események kezelésére is használhatók, például WebSocketekből származó események esetén. Létrehozhat egy aszinkron iterálható objektumot, amely az események beérkezésekor bocsátja ki azokat, majd a segédfüggvényekkel feldolgozhatja ezeket az eseményeket.
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); // A kapcsolat bezárásakor null értékkel oldódik fel
}
});
}
} finally {
ws.close();
}
}
const websocketURL = 'wss://example.com/events'; // Cserélje le a saját WebSocket URL-jére
const eventStream = createWebSocketStream(websocketURL);
// Az eseményfolyam feldolgozása
(async () => {
for await (const event of eventStream.filter(event => event.type === 'user_login').map(event => ({ userId: event.userId, timestamp: event.timestamp }))) {
console.log('Felhasználói bejelentkezési esemény:', event);
// A felhasználói bejelentkezési esemény feldolgozása
}
})();
Ebben a példában a createWebSocketStream
egy aszinkron iterálható objektumot hoz létre, amely a WebSocketről kapott eseményeket bocsátja ki. A filter
segédfüggvény csak a felhasználói bejelentkezési eseményeket választja ki, a map
segédfüggvény pedig a kívánt formátumra alakítja az adatokat.
Az Async Iterator segédfüggvények használatának előnyei
- Jobb kódolvashatóság és karbantarthatóság: Az Async Iterator segédfüggvények a funkcionális és kompozíciós programozási stílust támogatják, ami olvashatóbbá, érthetőbbé és karbantarthatóbbá teszi a kódot. A segédfüggvények láncolható természete lehetővé teszi az összetett adatfeldolgozási láncok tömör és deklaratív módon történő kifejezését.
- Hatékony memóriahasználat: Az Async Iterator segédfüggvények lustán (lazily) dolgozzák fel az adatfolyamokat, ami azt jelenti, hogy csak akkor dolgozzák fel az adatokat, amikor arra szükség van. Ez jelentősen csökkentheti a memóriahasználatot, különösen nagy adathalmazok vagy folyamatos adatfolyamok esetén.
- Fokozott teljesítmény: Az adatok folyamatos feldolgozásával az Async Iterator segédfüggvények javíthatják a teljesítményt, mivel elkerülik a teljes adathalmaz egyszerre történő memóriába töltésének szükségességét. Ez különösen előnyös lehet olyan alkalmazásoknál, amelyek nagy fájlokat, valós idejű adatokat vagy streaming API-kat kezelnek.
- Egyszerűsített aszinkron programozás: Az Async Iterator segédfüggvények elvonatkoztatják az aszinkron programozás bonyolultságait, megkönnyítve az aszinkron adatfolyamokkal való munkát. Nem kell manuálisan kezelnie a promise-okat vagy a visszahívásokat; a segédfüggvények a háttérben kezelik az aszinkron műveleteket.
- Komponálható és újrafelhasználható kód: Az Async Iterator segédfüggvényeket úgy tervezték, hogy komponálhatók legyenek, ami azt jelenti, hogy könnyen láncba fűzhetők összetett adatfeldolgozási láncok létrehozásához. Ez elősegíti a kód újrafelhasználását és csökkenti a kódduplikációt.
Böngésző- és futtatókörnyezeti támogatás
Az Async Iterator segédfüggvények még viszonylag új funkciónak számítanak a JavaScriptben. 2024 végén a TC39 szabványosítási folyamat 3. szakaszában vannak, ami azt jelenti, hogy valószínűleg a közeljövőben szabványosítva lesznek. Azonban még nem támogatottak natívan minden böngészőben és Node.js verzióban.
Böngészőtámogatás: A modern böngészők, mint a Chrome, a Firefox, a Safari és az Edge, fokozatosan vezetik be az Async Iterator segédfüggvények támogatását. A legfrissebb böngészőkompatibilitási információkat olyan webhelyeken ellenőrizheti, mint a Can I use..., hogy lássa, mely böngészők támogatják ezt a funkciót.
Node.js támogatás: A Node.js újabb verziói (v18 és újabbak) kísérleti támogatást nyújtanak az Async Iterator segédfüggvényekhez. Használatukhoz lehet, hogy a Node.js-t a --experimental-async-iterator
kapcsolóval kell futtatni.
Polyfillek: Ha olyan környezetekben kell használnia az Async Iterator segédfüggvényeket, amelyek natívan nem támogatják őket, használhat polyfillt. A polyfill egy kódrészlet, amely biztosítja a hiányzó funkcionalitást. Számos polyfill könyvtár érhető el az Async Iterator segédfüggvényekhez; egy népszerű lehetőség a core-js
könyvtár.
Egyéni aszinkron iterátorok implementálása
Bár az Async Iterator segédfüggvények kényelmes módot kínálnak a meglévő aszinkron iterálható objektumok feldolgozására, néha szükség lehet saját egyéni aszinkron iterátorok létrehozására. Ez lehetővé teszi, hogy különböző forrásokból, például adatbázisokból, API-kból vagy fájlrendszerekből származó adatokat streaming módon kezeljen.
Egyéni aszinkron iterátor létrehozásához implementálnia kell a @@asyncIterator
metódust egy objektumon. Ennek a metódusnak egy olyan objektumot kell visszaadnia, amely rendelkezik egy next()
metódussal. A next()
metódusnak egy promise-t kell visszaadnia, amely egy value
és done
tulajdonságokkal rendelkező objektumra oldódik fel.
Íme egy példa egy egyéni aszinkron iterátorra, amely adatokat kér le egy lapozott API-ból:
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'; // Cserélje le a saját API URL-jére
const paginatedData = fetchPaginatedData(apiBaseURL);
// A lapozott adatok feldolgozása
(async () => {
for await (const item of paginatedData) {
console.log('Elem:', item);
// Az elem feldolgozása
}
})();
Ebben a példában a fetchPaginatedData
adatokat kér le egy lapozott API-ból, és minden egyes elemet visszaad, amint azt lekérte. Az aszinkron iterátor kezeli a lapozási logikát, ami megkönnyíti az adatok streaming módon történő feldolgozását.
Lehetséges kihívások és megfontolások
Bár az Async Iterator segédfüggvények számos előnnyel járnak, fontos tisztában lenni néhány lehetséges kihívással és megfontolással:
- Hibakezelés: A megfelelő hibakezelés kulcsfontosságú az aszinkron adatfolyamokkal való munka során. Kezelnie kell az adatlekérés, -feldolgozás vagy -átalakítás során esetlegesen fellépő hibákat. A
try...catch
blokkok és hibakezelési technikák használata az aszinkron iterátor segédfüggvényeken belül elengedhetetlen. - Megszakítás: Bizonyos esetekben szükség lehet egy aszinkron iterálható objektum feldolgozásának megszakítására, mielőtt az teljesen befejeződne. Ez hasznos lehet hosszan futó műveletek vagy valós idejű adatfolyamok esetén, ahol egy bizonyos feltétel teljesülése után le akarja állítani a feldolgozást. A megszakítási mechanizmusok, például az
AbortController
használata segíthet az aszinkron műveletek hatékony kezelésében. - Visszanyomás (Backpressure): Amikor olyan adatfolyamokkal dolgozik, amelyek gyorsabban termelnek adatokat, mint ahogyan azokat fel lehet dolgozni, a visszanyomás (backpressure) problémát jelenthet. A visszanyomás arra utal, hogy a fogyasztó képes jelezni a termelőnek, hogy lassítsa az adatok kibocsátásának sebességét. A visszanyomási mechanizmusok implementálása megakadályozhatja a memória túlterhelését és biztosíthatja az adatfolyam hatékony feldolgozását.
- Hibakeresés (Debugging): Az aszinkron kód hibakeresése nagyobb kihívást jelenthet, mint a szinkron kódé. Az Async Iterator segédfüggvényekkel való munka során fontos hibakereső eszközöket és technikákat használni az adatok folyamatának nyomon követésére a láncon keresztül és az esetleges problémák azonosítására.
Az Async Iterator segédfüggvények használatának legjobb gyakorlatai
Ahhoz, hogy a legtöbbet hozza ki az Async Iterator segédfüggvényekből, vegye figyelembe a következő legjobb gyakorlatokat:
- Használjon leíró változóneveket: Válasszon leíró változóneveket, amelyek egyértelműen jelzik az egyes aszinkron iterálható objektumok és segédfüggvények célját. Ez olvashatóbbá és érthetőbbé teszi a kódját.
- Tartsa a segédfüggvényeket tömören: Az Async Iterator segédfüggvényeknek átadott függvényeket tartsa a lehető legtömörebben és legcélirányosabban. Kerülje a bonyolult műveletek végrehajtását ezeken a függvényeken belül; helyette hozzon létre külön függvényeket a komplex logikához.
- Láncolja a segédfüggvényeket az olvashatóság érdekében: Láncolja össze az Async Iterator segédfüggvényeket, hogy tiszta és deklaratív adatfeldolgozási láncot hozzon létre. Kerülje a segédfüggvények túlzott beágyazását, mert ez nehezebben olvashatóvá teheti a kódot.
- Kezelje a hibákat elegánsan: Implementáljon megfelelő hibakezelési mechanizmusokat az adatfeldolgozás során esetlegesen fellépő hibák elkapására és kezelésére. Adjon informatív hibaüzeneteket a problémák diagnosztizálásához és megoldásához.
- Tesztelje alaposan a kódját: Tesztelje alaposan a kódját, hogy megbizonyosodjon arról, hogy helyesen kezeli a különböző forgatókönyveket. Írjon egységteszteket az egyes segédfüggvények viselkedésének ellenőrzésére és integrációs teszteket a teljes adatfeldolgozási lánc ellenőrzésére.
Haladó technikák
Egyéni segédfüggvények komponálása
Létrehozhat saját egyéni aszinkron iterátor segédfüggvényeket meglévő segédfüggvények komponálásával vagy újak létrehozásával a semmiből. Ez lehetővé teszi, hogy a funkcionalitást saját specifikus igényeihez igazítsa és újrafelhasználható komponenseket hozzon létre.
async function* takeWhile(asyncIterable, predicate) {
for await (const value of asyncIterable) {
if (!predicate(value)) {
break;
}
yield value;
}
}
// Példa használat:
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);
}
})();
Több aszinkron iterálható objektum kombinálása
Több aszinkron iterálható objektumot egyetlen aszinkron iterálható objektummá kombinálhat olyan technikákkal, mint a zip
vagy a merge
. Ez lehetővé teszi, hogy több forrásból származó adatokat egyszerre dolgozzon fel.
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élda használat:
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);
}
})();
Összegzés
A JavaScript Async Iterator segédfüggvényei erőteljes és elegáns módot kínálnak az aszinkron adatfolyamok feldolgozására. Funkcionális és kompozíciós megközelítést biztosítanak az adatmanipulációhoz, megkönnyítve az összetett adatfeldolgozási láncok kiépítését. Az aszinkron iterátorok és aszinkron iterálható objektumok alapkoncepcióinak megértésével és a különböző segédmetódusok elsajátításával jelentősen javíthatja aszinkron JavaScript kódjának hatékonyságát és karbantarthatóságát. Ahogy a böngésző- és futtatókörnyezeti támogatás tovább növekszik, az Async Iterator segédfüggvények a modern JavaScript fejlesztők nélkülözhetetlen eszközévé válnak.