Põhjalik juhend JavaScripti voo lugejate kohta, mis käsitleb asünkroonset andmetöötlust, kasutusjuhtumeid, veahaldust ning parimaid praktikaid tõhusaks ja robustseks andmetöötluseks.
JavaScript'i voo lugeja: asünkroonne andmetarbimine
Web Streams API pakub võimsat mehhanismi andmevoogude asünkroonseks käsitlemiseks JavaScriptis. Selle API keskmes on ReadableStream liides, mis esindab andmeallikat, ja ReadableStreamReader liides, mis võimaldab teil tarbida andmeid ReadableStream'ist. See põhjalik juhend uurib JavaScripti voo lugejatega seotud kontseptsioone, kasutamist ja parimaid praktikaid, keskendudes asünkroonsele andmetarbimisele.
Veebivoogude ja voo lugejate mõistmine
Mis on veebivood?
Veebivood on kaasaegsete veebirakenduste asünkroonse andmetöötluse põhiline ehituskivi. Need võimaldavad teil töödelda andmeid järk-järgult, kui need muutuvad kättesaadavaks, selle asemel, et oodata kogu andmeallika laadimist. See on eriti kasulik suurte failide, võrgupäringute ja reaalajas andmevoogude käsitlemisel.
Veebivoogude kasutamise peamised eelised on järgmised:
- Parem jõudlus: Töötle andmeosi nende saabumisel, vähendades latentsust ja parandades reageerimisvõimet.
- Mäluefektiivsus: Käsitse suuri andmehulki ilma kogu andmestikku mällu laadimata.
- Asünkroonsed toimingud: Mitteblokeeriv andmetöötlus võimaldab kasutajaliidesel jääda reageerivaks.
- Torustamine ja teisendamine: Vooge saab torustada ja teisendada, võimaldades keerukaid andmetöötlusahelaid.
ReadableStream ja ReadableStreamReader
ReadableStream esindab andmeallikat, millest saate lugeda. Seda saab luua erinevatest allikatest, näiteks võrgupäringutest (kasutades fetch), failisüsteemi toimingutest või isegi kohandatud andmegeneraatoritest.
ReadableStreamReader on liides, mis võimaldab teil lugeda andmeid ReadableStream'ist. Saadaval on erinevat tüüpi lugejaid, sealhulgas:
ReadableStreamDefaultReader: Kõige levinum tüüp, mida kasutatakse baidivoogude lugemiseks.ReadableStreamBYOBReader: Kasutatakse "too oma puhver" (bring your own buffer) lugemiseks, mis võimaldab teil otse täita kaasasoleva puhvri andmetega. See on eriti tõhus nullkoopiaga (zero-copy) toimingute puhul.ReadableStreamTextDecoder(mitte otsene lugeja, kuid seotud): Kasutatakse sageli koos lugejaga tekstiandmete dekodeerimiseks baidivoost.
ReadableStreamDefaultReader'i põhikasutus
Alustame põhinäitega andmete lugemisest ReadableStream'ist, kasutades ReadableStreamDefaultReader'it.
Näide: Lugemine Fetch vastusest
See näide demonstreerib, kuidas hankida andmeid URL-ist ja lugeda neid voona:
async function readStreamFromURL(url) {
const response = await fetch(url);
const reader = response.body.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log("Stream complete");
break;
}
// Process the data chunk (value is a Uint8Array)
console.log("Received chunk:", value);
}
} catch (error) {
console.error("Error reading from stream:", error);
} finally {
reader.releaseLock(); // Release the lock when done
}
}
// Example usage
readStreamFromURL("https://example.com/large_data.txt");
Selgitus:
fetch(url): Hangib andmed määratud URL-ilt.response.body.getReader(): HangibReadableStreamDefaultReader'i vastuse kehast (body).reader.read(): Loeb asünkroonselt voost andmeosa. Tagastab lubaduse (promise), mis laheneb objektiks, millel ondonejavalueomadused.done: Boole'i väärtus, mis näitab, kas voog on täielikult loetud.value:Uint8Array, mis sisaldab andmeosa.- Tsükkel:
whiletsükkel jätkab andmete lugemist, kunidoneon tõene. - Veahaldus:
try...catchplokk käsitleb võimalikke vigu voo lugemise ajal. reader.releaseLock(): Vabastab lugeja luku, võimaldades teistel tarbijatel voole juurde pääseda. See on ülioluline mälulekete vältimiseks ja ressursside korrektse haldamise tagamiseks.
Asünkroonne iteratsioon for-await-of abil
ReadableStream'ist lugemiseks on lühem viis, kasutades for-await-of tsüklit:
async function readStreamFromURL_forAwait(url) {
const response = await fetch(url);
const reader = response.body;
try {
for await (const chunk of reader) {
// Process the data chunk (chunk is a Uint8Array)
console.log("Received chunk:", chunk);
}
console.log("Stream complete");
} catch (error) {
console.error("Error reading from stream:", error);
}
}
// Example usage
readStreamFromURL_forAwait("https://example.com/large_data.txt");
See lähenemine lihtsustab koodi ja parandab loetavust. for-await-of tsükkel tegeleb automaatselt asünkroonse iteratsiooni ja voo lõpetamisega.
Teksti dekodeerimine ReadableStreamTextDecoder'iga
Sageli peate dekodeerima tekstiandmeid baidivoost. TextDecoder API-d saab kasutada koos ReadableStreamReader'iga, et seda tõhusalt käsitleda.
Näide: Teksti dekodeerimine voost
async function readTextFromStream(url, encoding = 'utf-8') {
const response = await fetch(url);
const reader = response.body.getReader();
const decoder = new TextDecoder(encoding);
try {
let accumulatedText = '';
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log("Stream complete");
break;
}
const textChunk = decoder.decode(value, { stream: true });
accumulatedText += textChunk;
console.log("Received and decoded chunk:", textChunk);
}
console.log("Accumulated Text: ", accumulatedText);
} catch (error) {
console.error("Error reading from stream:", error);
} finally {
reader.releaseLock();
}
}
// Example usage
readTextFromStream("https://example.com/text_data.txt", 'utf-8');
Selgitus:
TextDecoder(encoding): LoobTextDecoderobjekti määratud kodeeringuga (nt 'utf-8', 'iso-8859-1').decoder.decode(value, { stream: true }): DekodeeribUint8Array(value) stringiks. Valik{ stream: true }on ülioluline mitmebaidiliste märkide käsitlemiseks, mis võivad olla osade vahel poolitatud. See säilitab dekoodri sisemise oleku kutsete vahel.- Kogumine: Kuna voog võib edastada märke osadena, kogutakse dekodeeritud stringid muutujasse
accumulatedText, et tagada täielike märkide töötlemine.
Vigade käsitlemine ja voo tühistamine
Tugev veahaldus on voogudega töötamisel hädavajalik. Siin on, kuidas käsitleda vigu ja tühistada vooge sujuvalt.
Veahaldus
Eelmistes näidetes olev try...catch plokk käsitleb lugemisprotsessi ajal tekkivaid vigu. Siiski saate käsitleda ka vigu, mis võivad tekkida voo loomisel või andmeosade töötlemisel.
Voo tühistamine
Saate voo tühistada, et andmevoog peatada. See on kasulik, kui te ei vaja enam andmeid või kui tekib viga, millest ei saa taastuda.
async function cancelStream(url) {
const controller = new AbortController();
const signal = controller.signal;
try {
const response = await fetch(url, { signal });
const reader = response.body.getReader();
setTimeout(() => {
console.log("Cancelling stream...");
controller.abort(); // Cancel the fetch request
}, 5000); // Cancel after 5 seconds
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log("Stream complete");
break;
}
// Process the data chunk
console.log("Received chunk:", value);
}
} catch (error) {
console.error("Error reading from stream:", error);
if (error.name === 'AbortError') {
console.log('Stream aborted by user');
}
} finally {
// It's good practice to always release the lock
// even after an error.
if(reader) {
reader.releaseLock();
}
}
}
// Example usage
cancelStream("https://example.com/large_data.txt");
Selgitus:
AbortController: LoobAbortController'i, mis võimaldab teil anda signaali tühistamistaotluseks.signal:AbortController'i omadussignaledastataksefetchvalikutele.controller.abort():abort()kutsumine annab signaali tühistamiseks.- Veahaldus:
catchplokk kontrollib, kas viga onAbortError, mis näitab, et voog tühistati. - Luku vabastamine: `finally` plokk tagab, et `reader.releaseLock()` kutsutakse isegi vea ilmnemisel, et vältida mälulekkeid.
ReadableStreamBYOBReader: too oma puhver
ReadableStreamBYOBReader võimaldab teil otse täita kaasasoleva puhvri voost pärinevate andmetega. See on eriti kasulik nullkoopiaga (zero-copy) toimingute puhul, kus soovite vältida tarbetut andmete kopeerimist. Pange tähele, et BYOB-lugejad vajavad spetsiaalselt nende toetamiseks loodud voogu ja ei pruugi kõigi `ReadableStream` allikatega töötada. Nende kasutamine tagab üldiselt parema jõudluse binaarandmete puhul.
Vaatleme seda (mõnevõrra konstrueeritud) näidet, et illustreerida `ReadableStreamBYOBReader`'i kasutamist:
async function readWithBYOB(url) {
const response = await fetch(url);
// Check if the stream is BYOB-compatible.
if (!response.body.readable || !response.body.readable.pipeTo) {
console.error("Stream is not BYOB-compatible.");
return;
}
const stream = response.body.readable;
// Create a Uint8Array to hold the data.
const bufferSize = 1024; // Define an appropriate buffer size.
const buffer = new Uint8Array(bufferSize);
const reader = stream.getReader({ mode: 'byob' });
try {
while (true) {
const { done, value } = await reader.read(buffer);
if (done) {
console.log("BYOB Stream complete.");
break;
}
// 'value' is the same Uint8Array you passed to 'read'.
// Only the section of the buffer filled by this read
// is guaranteed to contain valid data. Check `value.byteLength`
// to see how many bytes were actually written.
console.log(`Read ${value.byteLength} bytes into the buffer.`);
// Process the filled portion of the buffer. For example:
// for (let i = 0; i < value.byteLength; i++) {
// console.log(value[i]); // Process each byte
// }
}
} catch (error) {
console.error("Error during BYOB stream reading:", error);
} finally {
reader.releaseLock();
}
}
// Example Usage
readWithBYOB("https://example.com/binary_data.bin");
Selle näite põhiaspektid:
- BYOB ühilduvus: Mitte kõik vood ei ühildu BYOB lugejatega. Tavaliselt vajate serverit, mis mõistab ja toetab andmete saatmist selle tarbimisviisi jaoks optimeeritud viisil. Näites on olemas elementaarne kontroll.
- Puhvri eraldamine: Loote
Uint8Array, mis toimib puhvrina, kuhu andmed otse loetakse. - BYOB lugeja hankimine: Kasutage `stream.getReader({mode: 'byob'})`, et luua `ReadableStreamBYOBReader`.
- `reader.read(buffer)`: Selle asemel, et kutsuda `reader.read()`, mis tagastab uue massiivi, kutsute `reader.read(buffer)`, andes kaasa oma eelnevalt eraldatud puhvri.
- Andmete töötlemine: `reader.read(buffer)` poolt tagastatud `value` *on* sama puhver, mille te kaasa andsite. Siiski teate ainult, et puhvri osa kuni `value.byteLength` sisaldab kehtivaid andmeid. Peate jälgima, mitu baiti tegelikult kirjutati.
Praktilised kasutusjuhud
1. Suurte logifailide töötlemine
Veebivood on ideaalsed suurte logifailide töötlemiseks ilma kogu faili mällu laadimata. Saate lugeda faili rida-realt ja töödelda iga rida selle kättesaadavaks muutumisel. See on eriti kasulik serveri logide, rakenduste logide või muude suurte tekstifailide analüüsimisel.
2. Reaalajas andmevood
Veebivooge saab kasutada reaalajas andmevoogude tarbimiseks, näiteks aktsiahinnad, andurite andmed või sotsiaalmeedia uuendused. Saate luua ühenduse andmeallikaga ja töödelda sissetulevaid andmeid nende saabumisel, uuendades kasutajaliidest reaalajas.
3. Video voogedastus
Veebivood on kaasaegsete video voogedastustehnoloogiate põhikomponent. Saate hankida videoandmeid osadena ja dekodeerida iga osa selle saabumisel, võimaldades sujuvat ja tõhusat video taasesitust. Seda kasutavad populaarsed video voogedastusplatvormid nagu YouTube ja Netflix.
4. Failide üleslaadimine
Veebivooge saab kasutada failide üleslaadimise tõhusamaks haldamiseks. Saate lugeda failiandmeid osadena ja saata iga osa serverisse selle kättesaadavaks muutumisel, vähendades mälujalajälge kliendi poolel.
Parimad praktikad
- Vabastage alati lukk: Kutsuge
reader.releaseLock(), kui olete vooga lõpetanud, et vältida mälulekkeid ja tagada ressursside korrektne haldamine. Kasutagefinallyplokki, et garanteerida luku vabastamine isegi vea ilmnemisel. - Käsitlege vigu sujuvalt: Rakendage robustne veahaldus, et püüda kinni ja käsitleda võimalikke vigu voo lugemise ajal. Pakkuge kasutajale informatiivseid veateateid.
- Kasutage tekstiandmete jaoks TextDecoder'it: Kasutage
TextDecoderAPI-d tekstiandmete dekodeerimiseks baidivoogudest. Pidage meeles, et mitmebaidiliste märkide jaoks tuleb kasutada valikut{ stream: true }. - Kaaluge binaarandmete jaoks BYOB lugejaid: Kui töötate binaarandmetega ja vajate maksimaalset jõudlust, kaaluge
ReadableStreamBYOBReader'i kasutamist. - Kasutage tühistamiseks AbortController'it: Kasutage
AbortController'it, et vooge sujuvalt tühistada, kui te andmeid enam ei vaja. - Valige sobivad puhvri suurused: BYOB lugejate kasutamisel valige sobiv puhvri suurus, lähtudes oodatavast andmeosa suurusest.
- Vältige blokeerivaid toiminguid: Veenduge, et teie andmetöötlusloogika on mitteblokeeriv, et vältida kasutajaliidese hangumist. Kasutage asünkroonsete toimingute tegemiseks
async/await. - Olge teadlik märgikodeeringutest: Teksti dekodeerimisel veenduge, et kasutate õiget märgikodeeringut, et vältida moonutatud teksti.
Kokkuvõte
JavaScripti voo lugejad pakuvad võimsat ja tõhusat viisi asünkroonseks andmetarbimiseks kaasaegsetes veebirakendustes. Mõistes selles juhendis kirjeldatud kontseptsioone, kasutamist ja parimaid praktikaid, saate kasutada veebivooge oma rakenduste jõudluse, mäluefektiivsuse ja reageerimisvõime parandamiseks. Alates suurte failide töötlemisest kuni reaalajas andmevoogude tarbimiseni pakuvad veebivood mitmekülgset lahendust laiale valikule andmetöötlusülesannetele. Kuna Web Streams API areneb edasi, mängib see kahtlemata üha olulisemat rolli veebiarenduse tulevikus.