Raziščite pomočnike za asinhroni iterator v JavaScriptu za revolucijo v obdelavi tokov. Naučite se učinkovito upravljati asinhrone podatkovne tokove z map, filter, take, drop in drugimi.
Pomočniki za asinhroni iterator v JavaScriptu: Zmogljiva obdelava tokov za sodobne aplikacije
Pri sodobnem razvoju JavaScripta je obravnavanje asinhronih podatkovnih tokov pogosta zahteva. Ne glede na to, ali pridobivate podatke iz API-ja, obdelujete velike datoteke ali upravljate dogodke v realnem času, je učinkovito upravljanje asinhronih podatkov ključnega pomena. Pomočniki za asinhroni iterator v JavaScriptu zagotavljajo zmogljiv in eleganten način za obdelavo teh tokov, saj ponujajo funkcionalen in sestavljiv pristop k manipulaciji podatkov.
Kaj so asinhroni iteratorji in asinhroni iterabilni objekti?
Preden se poglobimo v pomočnike za asinhroni iterator, si poglejmo temeljne koncepte: asinhroni iteratorji in asinhroni iterabilni objekti.
Asinhroni iterabilni objekt (Async Iterable) je objekt, ki določa način za asinhrono iteracijo preko svojih vrednosti. To stori z implementacijo metode @@asyncIterator
, ki vrne asinhroni iterator (Async Iterator).
Asinhroni iterator (Async Iterator) je objekt, ki ponuja metodo next()
. Ta metoda vrne obljubo (promise), ki se razreši v objekt z dvema lastnostma:
value
: Naslednja vrednost v zaporedju.done
: Logična vrednost, ki označuje, ali je bilo zaporedje v celoti porabljeno.
Tukaj je preprost primer:
async function* generateSequence(end) {
for (let i = 1; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Simulacija asinhrone operacije
yield i;
}
}
const asyncIterable = generateSequence(5);
(async () => {
for await (const value of asyncIterable) {
console.log(value); // Izhod: 1, 2, 3, 4, 5 (s 500ms zamikom med vsakim)
}
})();
V tem primeru je generateSequence
asinhrona generatorska funkcija, ki asinhrono proizvaja zaporedje števil. Zanka for await...of
se uporablja za porabo vrednosti iz asinhrono iterabilnega objekta.
Predstavitev pomočnikov za asinhroni iterator
Pomočniki za asinhroni iterator razširjajo funkcionalnost asinhronih iteratorjev in ponujajo nabor metod za transformacijo, filtriranje in manipulacijo asinhronih podatkovnih tokov. Omogočajo funkcionalen in sestavljiv stil programiranja, kar olajša gradnjo kompleksnih cevovodov za obdelavo podatkov.
Osnovni pomočniki za asinhroni iterator vključujejo:
map()
: Transformira vsak element toka.filter()
: Izbere elemente iz toka na podlagi pogoja.take()
: Vrne prvih N elementov toka.drop()
: Preskoči prvih N elementov toka.toArray()
: Zbere vse elemente toka v polje.forEach()
: Za vsak element toka enkrat izvede podano funkcijo.some()
: Preveri, ali vsaj en element izpolnjuje podan pogoj.every()
: Preveri, ali vsi elementi izpolnjujejo podan pogoj.find()
: Vrne prvi element, ki izpolnjuje podan pogoj.reduce()
: Uporabi funkcijo na akumulatorju in vsakem elementu, da ga zreducira na eno samo vrednost.
Raziščimo vsakega pomočnika s primeri.
map()
Pomočnik map()
transformira vsak element asinhrono iterabilnega objekta z uporabo podane funkcije. Vrne nov asinhrono iterabilen objekt s transformiranimi vrednostmi.
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); // Izhod: 2, 4, 6, 8, 10 (s 100ms zamikom)
}
})();
V tem primeru map(x => x * 2)
podvoji vsako število v zaporedju.
filter()
Pomočnik filter()
izbere elemente iz asinhrono iterabilnega objekta na podlagi podanega pogoja (predikatne funkcije). Vrne nov asinhrono iterabilen objekt, ki vsebuje samo elemente, ki izpolnjujejo pogoj.
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); // Izhod: 2, 4, 6, 8, 10 (s 100ms zamikom)
}
})();
V tem primeru filter(x => x % 2 === 0)
izbere samo soda števila iz zaporedja.
take()
Pomočnik take()
vrne prvih N elementov iz asinhrono iterabilnega objekta. Vrne nov asinhrono iterabilen objekt, ki vsebuje samo določeno število elementov.
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); // Izhod: 1, 2, 3 (s 100ms zamikom)
}
})();
V tem primeru take(3)
izbere prva tri števila iz zaporedja.
drop()
Pomočnik drop()
preskoči prvih N elementov iz asinhrono iterabilnega objekta in vrne preostanek. Vrne nov asinhrono iterabilen objekt, ki vsebuje preostale elemente.
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); // Izhod: 3, 4, 5 (s 100ms zamikom)
}
})();
V tem primeru drop(2)
preskoči prvi dve števili iz zaporedja.
toArray()
Pomočnik toArray()
porabi celoten asinhrono iterabilen objekt in zbere vse elemente v polje. Vrne obljubo, ki se razreši v polje, ki vsebuje vse elemente.
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); // Izhod: [1, 2, 3, 4, 5]
})();
V tem primeru toArray()
zbere vsa števila iz zaporedja v polje.
forEach()
Pomočnik forEach()
za vsak element v asinhrono iterabilnem objektu enkrat izvede podano funkcijo. Ne vrne novega asinhrono iterabilnega objekta, temveč funkcijo izvede s stranskim učinkom. To je lahko koristno za izvajanje operacij, kot so beleženje ali posodabljanje uporabniškega vmesnika.
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");
})();
// Izhod: Value: 1, Value: 2, Value: 3, forEach completed
some()
Pomočnik some()
preverja, ali vsaj en element v asinhrono iterabilnem objektu izpolnjuje test, ki ga izvaja podana funkcija. Vrne obljubo, ki se razreši v logično vrednost (true
, če vsaj en element izpolnjuje pogoj, sicer 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); // Izhod: Has even number: true
})();
every()
Pomočnik every()
preverja, ali vsi elementi v asinhrono iterabilnem objektu izpolnjujejo test, ki ga izvaja podana funkcija. Vrne obljubo, ki se razreši v logično vrednost (true
, če vsi elementi izpolnjujejo pogoj, sicer 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); // Izhod: Are all even: true
})();
find()
Pomočnik find()
vrne prvi element v asinhrono iterabilnem objektu, ki izpolnjuje podano testno funkcijo. Če nobena vrednost ne izpolnjuje testne funkcije, se vrne undefined
. Vrne obljubo, ki se razreši v najdeni element ali 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("First even number:", firstEven); // Izhod: First even number: 2
})();
reduce()
Pomočnik reduce()
izvede uporabniško določeno "reducer" povratno funkcijo na vsakem elementu asinhrono iterabilnega objekta po vrsti, pri čemer posreduje vrnjeno vrednost iz izračuna na prejšnjem elementu. Končni rezultat izvajanja reducerja na vseh elementih je ena sama vrednost. Vrne obljubo, ki se razreši v končno akumulirano vrednost.
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); // Izhod: Sum: 15
})();
Praktični primeri in primeri uporabe
Pomočniki za asinhroni iterator so dragoceni v različnih scenarijih. Poglejmo si nekaj praktičnih primerov:
1. Obdelava podatkov iz pretočnega API-ja (Streaming API)
Predstavljajte si, da gradite nadzorno ploščo za vizualizacijo podatkov v realnem času, ki prejema podatke iz pretočnega API-ja. API nenehno pošilja posodobitve in te posodobitve morate obdelati, da prikažete najnovejše informacije.
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);
// Predpostavimo, da API pošilja objekte JSON, ločene z novimi vrsticami
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'; // Zamenjajte z URL-jem vašega API-ja
const dataStream = fetchDataFromAPI(apiURL);
// Obdelajte podatkovni tok
(async () => {
for await (const data of dataStream.filter(item => item.type === 'metric').map(item => ({ timestamp: item.timestamp, value: item.value }))) {
console.log('Processed Data:', data);
// Posodobite nadzorno ploščo z obdelanimi podatki
}
})();
V tem primeru fetchDataFromAPI
pridobiva podatke iz pretočnega API-ja, razčleni objekte JSON in jih vrne kot asinhrono iterabilen objekt. Pomočnik filter
izbere samo metrike, pomočnik map
pa preoblikuje podatke v želeno obliko pred posodobitvijo nadzorne plošče.
2. Branje in obdelava velikih datotek
Recimo, da morate obdelati veliko datoteko CSV, ki vsebuje podatke o strankah. Namesto da bi celotno datoteko naložili v pomnilnik, jo lahko z uporabo pomočnikov za asinhroni iterator obdelate po delih.
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'; // Zamenjajte s potjo do vaše datoteke
const lines = readLinesFromFile(filePath);
// Obdelajte vrstice
(async () => {
for await (const customerData of lines.drop(1).map(line => line.split(',')).filter(data => data[2] === 'USA')) {
console.log('Customer from USA:', customerData);
// Obdelajte podatke o strankah iz ZDA
}
})();
V tem primeru readLinesFromFile
bere datoteko vrstico za vrstico in vsako vrstico vrne kot asinhrono iterabilen objekt. Pomočnik drop(1)
preskoči naslovno vrstico, pomočnik map
razdeli vrstico na stolpce, pomočnik filter
pa izbere samo stranke iz ZDA.
3. Obravnavanje dogodkov v realnem času
Pomočnike za asinhroni iterator lahko uporabimo tudi za obravnavo dogodkov v realnem času iz virov, kot so WebSockets. Ustvarite lahko asinhrono iterabilen objekt, ki oddaja dogodke, ko prispejo, in nato uporabite pomočnike za obdelavo teh dogodkov.
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); // Razreši z null, ko se povezava zapre
}
});
}
} finally {
ws.close();
}
}
const websocketURL = 'wss://example.com/events'; // Zamenjajte z URL-jem vašega WebSocket-a
const eventStream = createWebSocketStream(websocketURL);
// Obdelajte tok dogodkov
(async () => {
for await (const event of eventStream.filter(event => event.type === 'user_login').map(event => ({ userId: event.userId, timestamp: event.timestamp }))) {
console.log('User Login Event:', event);
// Obdelajte dogodek prijave uporabnika
}
})();
V tem primeru createWebSocketStream
ustvari asinhrono iterabilen objekt, ki oddaja dogodke, prejete iz WebSocket-a. Pomočnik filter
izbere samo dogodke prijave uporabnikov, pomočnik map
pa preoblikuje podatke v želeno obliko.
Prednosti uporabe pomočnikov za asinhroni iterator
- Izboljšana berljivost in vzdržljivost kode: Pomočniki za asinhroni iterator spodbujajo funkcionalen in sestavljiv stil programiranja, kar olajša branje, razumevanje in vzdrževanje vaše kode. Veriženje pomočnikov omogoča izražanje kompleksnih cevovodov za obdelavo podatkov na jedrnat in deklarativen način.
- Učinkovita uporaba pomnilnika: Pomočniki za asinhroni iterator obdelujejo podatkovne tokove lenobno (lazily), kar pomeni, da obdelujejo podatke samo po potrebi. To lahko bistveno zmanjša porabo pomnilnika, zlasti pri delu z velikimi nabori podatkov ali neprekinjenimi podatkovnimi tokovi.
- Povečana zmogljivost: Z obdelavo podatkov v toku lahko pomočniki za asinhroni iterator izboljšajo zmogljivost, saj se izognejo potrebi po nalaganju celotnega nabora podatkov v pomnilnik naenkrat. To je lahko še posebej koristno za aplikacije, ki obdelujejo velike datoteke, podatke v realnem času ali pretočne API-je.
- Poenostavljeno asinhrono programiranje: Pomočniki za asinhroni iterator abstrahirajo zapletenost asinhronega programiranja, kar olajša delo z asinhronimi podatkovnimi tokovi. Ni vam treba ročno upravljati obljub (promises) ali povratnih klicev (callbacks); pomočniki se ukvarjajo z asinhronimi operacijami v ozadju.
- Sestavljiva in ponovno uporabna koda: Pomočniki za asinhroni iterator so zasnovani tako, da so sestavljivi, kar pomeni, da jih lahko enostavno verižite skupaj za ustvarjanje kompleksnih cevovodov za obdelavo podatkov. To spodbuja ponovno uporabo kode in zmanjšuje njeno podvajanje.
Podpora v brskalnikih in izvajalskih okoljih
Pomočniki za asinhroni iterator so še vedno razmeroma nova funkcionalnost v JavaScriptu. Konec leta 2024 so v 3. fazi standardizacijskega postopka TC39, kar pomeni, da bodo verjetno standardizirani v bližnji prihodnosti. Vendar pa še niso izvorno podprti v vseh brskalnikih in različicah Node.js.
Podpora v brskalnikih: Sodobni brskalniki, kot so Chrome, Firefox, Safari in Edge, postopoma dodajajo podporo za pomočnike za asinhroni iterator. Najnovejše informacije o združljivosti brskalnikov lahko preverite na spletnih straneh, kot je Can I use..., da vidite, kateri brskalniki podpirajo to funkcijo.
Podpora v Node.js: Novejše različice Node.js (v18 in novejše) zagotavljajo eksperimentalno podporo za pomočnike za asinhroni iterator. Za njihovo uporabo boste morda morali zagnati Node.js z zastavico --experimental-async-iterator
.
Polyfills: Če morate uporabljati pomočnike za asinhroni iterator v okoljih, ki jih izvorno ne podpirajo, lahko uporabite polyfill. Polyfill je del kode, ki zagotavlja manjkajočo funkcionalnost. Na voljo je več knjižnic s polyfilli za pomočnike za asinhroni iterator; priljubljena možnost je knjižnica core-js
.
Implementacija asinhronih iteratorjev po meri
Čeprav pomočniki za asinhroni iterator zagotavljajo priročen način za obdelavo obstoječih asinhrono iterabilnih objektov, boste morda včasih morali ustvariti lastne asinhrone iteratorje po meri. To vam omogoča obravnavo podatkov iz različnih virov, kot so baze podatkov, API-ji ali datotečni sistemi, na pretočen način.
Za ustvarjanje asinhronih iteratorjev po meri morate na objektu implementirati metodo @@asyncIterator
. Ta metoda naj bi vrnila objekt z metodo next()
. Metoda next()
naj bi vrnila obljubo, ki se razreši v objekt z lastnostma value
in done
.
Tukaj je primer asinhronih iteratorjev po meri, ki pridobivajo podatke iz paginiranega API-ja:
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'; // Zamenjajte z URL-jem vašega API-ja
const paginatedData = fetchPaginatedData(apiBaseURL);
// Obdelajte paginirane podatke
(async () => {
for await (const item of paginatedData) {
console.log('Item:', item);
// Obdelajte element
}
})();
V tem primeru fetchPaginatedData
pridobiva podatke iz paginiranega API-ja in vsak element vrne, ko je pridobljen. Asinhroni iterator obravnava logiko paginacije, kar omogoča enostavno porabo podatkov na pretočen način.
Potencialni izzivi in premisleki
Čeprav pomočniki za asinhroni iterator ponujajo številne prednosti, je pomembno, da se zavedate nekaterih potencialnih izzivov in premislekov:
- Obravnavanje napak: Pravilno obravnavanje napak je ključnega pomena pri delu z asinhronimi podatkovnimi tokovi. Obravnavati morate morebitne napake, ki se lahko pojavijo med pridobivanjem, obdelavo ali transformacijo podatkov. Uporaba blokov
try...catch
in tehnik obravnavanja napak znotraj vaših pomočnikov za asinhroni iterator je bistvena. - Preklic: V nekaterih scenarijih boste morda morali preklicati obdelavo asinhrono iterabilnega objekta, preden je v celoti porabljen. To je lahko koristno pri dolgotrajnih operacijah ali podatkovnih tokovih v realnem času, kjer želite ustaviti obdelavo po izpolnitvi določenega pogoja. Implementacija mehanizmov za preklic, kot je uporaba
AbortController
, vam lahko pomaga učinkovito upravljati asinhrone operacije. - Povratni pritisk (Backpressure): Pri delu s podatkovnimi tokovi, ki proizvajajo podatke hitreje, kot jih je mogoče porabiti, postane povratni pritisk skrb. Povratni pritisk se nanaša na sposobnost porabnika, da proizvajalcu sporoči, naj upočasni hitrost oddajanja podatkov. Implementacija mehanizmov za povratni pritisk lahko prepreči preobremenitev pomnilnika in zagotovi učinkovito obdelavo podatkovnega toka.
- Odpravljanje napak: Odpravljanje napak v asinhroni kodi je lahko bolj zahtevno kot odpravljanje napak v sinhroni kodi. Pri delu s pomočniki za asinhroni iterator je pomembno uporabljati orodja in tehnike za odpravljanje napak, da sledite toku podatkov skozi cevovod in prepoznate morebitne težave.
Najboljše prakse za uporabo pomočnikov za asinhroni iterator
Da bi kar najbolje izkoristili pomočnike za asinhroni iterator, upoštevajte naslednje najboljše prakse:
- Uporabljajte opisna imena spremenljivk: Izberite opisna imena spremenljivk, ki jasno kažejo namen vsakega asinhrono iterabilnega objekta in pomočnika. To bo olajšalo branje in razumevanje vaše kode.
- Ohranite pomožne funkcije jedrnate: Funkcije, ki jih posredujete pomočnikom za asinhroni iterator, naj bodo čim bolj jedrnate in osredotočene. Izogibajte se izvajanju zapletenih operacij znotraj teh funkcij; raje ustvarite ločene funkcije za zapleteno logiko.
- Verižite pomočnike za boljšo berljivost: Pomočnike za asinhroni iterator verižite skupaj, da ustvarite jasen in deklarativen cevovod za obdelavo podatkov. Izogibajte se pretiranemu gnezdenju pomočnikov, saj lahko to oteži branje vaše kode.
- Elegantno obravnavajte napake: Implementirajte ustrezne mehanizme za obravnavanje napak, da ujamete in obravnavate morebitne napake, ki se lahko pojavijo med obdelavo podatkov. Zagotovite informativna sporočila o napakah, ki pomagajo pri diagnosticiranju in reševanju težav.
- Temeljito testirajte svojo kodo: Temeljito testirajte svojo kodo, da zagotovite, da pravilno obravnava različne scenarije. Napišite enotne teste za preverjanje delovanja posameznih pomočnikov in integracijske teste za preverjanje celotnega cevovoda za obdelavo podatkov.
Napredne tehnike
Sestavljanje pomočnikov po meri
Lahko ustvarite lastne pomočnike za asinhroni iterator po meri s sestavljanjem obstoječih pomočnikov ali z gradnjo novih iz nič. To vam omogoča, da funkcionalnost prilagodite svojim specifičnim potrebam in ustvarite ponovno uporabne komponente.
async function* takeWhile(asyncIterable, predicate) {
for await (const value of asyncIterable) {
if (!predicate(value)) {
break;
}
yield value;
}
}
// Primer uporabe:
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);
}
})();
Združevanje več asinhrono iterabilnih objektov
Več asinhrono iterabilnih objektov lahko združite v enega samega z uporabo tehnik, kot sta zip
ali merge
. To vam omogoča sočasno obdelavo podatkov iz več virov.
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];
}
}
// Primer uporabe:
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);
}
})();
Zaključek
Pomočniki za asinhroni iterator v JavaScriptu zagotavljajo zmogljiv in eleganten način za obdelavo asinhronih podatkovnih tokov. Ponujajo funkcionalen in sestavljiv pristop k manipulaciji podatkov, kar olajša gradnjo kompleksnih cevovodov za obdelavo podatkov. Z razumevanjem temeljnih konceptov asinhronih iteratorjev in asinhrono iterabilnih objektov ter z obvladovanjem različnih pomožnih metod lahko bistveno izboljšate učinkovitost in vzdržljivost vaše asinhrone JavaScript kode. Ker podpora v brskalnikih in izvajalskih okoljih še naprej raste, so pomočniki za asinhroni iterator pripravljeni postati bistveno orodje za sodobne razvijalce JavaScripta.