Node.js srautai gali būti sudėtingi, tačiau verta skirti laiko jiems suprasti.

Key Takeaways

  • Node.js srautai yra pagrindinis duomenų apdorojimo ir perdavimo įrankis, todėl jie idealiai tinka realaus laiko ir įvykiais pagrįstoms programoms.
  • Norėdami sukurti įrašomą srautą Node.js, galite naudoti fs modulio funkciją createWriteStream(), kuri įrašo duomenis į konkrečią vietą.
  • Skaitomi, rašomi, dvipusiai ir transformuojami yra keturi Node.js srautų tipai, kurių kiekvienas turi savo naudojimo atvejį ir funkcijas.

Srautas yra pagrindinis programavimo įrankis, susijęs su duomenų srautu. Savo esme srautas paprastai reiškia nuoseklų baitų perkėlimą iš vieno taško į kitą. Oficialioje Node.js dokumentacijoje srautas apibrėžiamas kaip abstrakti sąsaja, kurią galite naudoti dirbdami su duomenimis.

Duomenų perkėlimas kompiuteryje arba tinkle yra idealus srauto naudojimas.

Srautas Node.js

Srautai suvaidino esminį vaidmenį Node.js sėkmei. Jie idealiai tinka duomenų apdorojimui realiuoju laiku ir įvykiais pagrįstoms programoms – dviem svarbioms Node.js vykdymo aplinkos ypatybėms.

instagram viewer

Norėdami sukurti naują srautą Node.js, turėsite naudoti srauto API, kuri veikia tik su eilutėmis ir Node.js buferio duomenys. Node.js turi keturių tipų srautus: įrašomus, skaitomus, dvipusius ir transformuojančius.

Kaip sukurti ir naudoti rašomą srautą

Rašomas srautas leidžia rašyti arba siųsti duomenis į konkrečią vietą. Fs (failų sistemos) modulis turi WriteStream klasę, kurią galite naudoti norėdami sukurti naują srautą su fs.createWriteStream() funkcija. Ši funkcija priima kelią į failą, į kurį norite įrašyti duomenis, ir pasirenkamą parinkčių masyvą.

const {createWriteStream} = require("fs");

(() => {
const file = "myFile.txt";
const myWriteStream = createWriteStream(file);
let x = 0;
const writeNumber = 10000;

const writeData = () => {
while (x < writeNumber) {
const chunk = Buffer.from(`${x}, `, "utf-8");
if (x writeNumber - 1) return myWriteStream.end(chunk);
if (!myWriteStream.write(chunk)) break;
x++
}
};

writeData();
})();

Šis kodas importuoja CreateWriteStream() funkcija, kuri anoniminės rodyklės funkcija tada naudoja sukurti srautą, kuris įrašo duomenis į failą myFile.txt. Anoniminėje funkcijoje yra vidinė funkcija, vadinama writeData () kuri rašo duomenis.

The CreateWriteStream() funkcija veikia su buferiu, kad įrašytų skaičių rinkinį (0–9 999) į paskirties failą. Tačiau paleidus aukščiau pateiktą scenarijų, jis sukuria failą tame pačiame kataloge, kuriame yra šie duomenys:

Dabartinė skaičių kolekcija baigiasi ties 2 915, tačiau ji turėjo apimti skaičius iki 9 999. Šis neatitikimas atsiranda dėl to, kad kiekvienas WriteStream naudoja buferį, kuriame vienu metu saugomas fiksuotas kiekis duomenų. Norėdami sužinoti, kas yra ši numatytoji reikšmė, turėsite pasikonsultuoti su HighWaterMark variantas.

console.log("The highWaterMark value is: " +
myWriteStream.writableHighWaterMark + " bytes.");

Pridėjus aukščiau esančią kodo eilutę prie anoniminės funkcijos, terminale bus pateikta tokia išvestis:

Terminalo išvestis rodo, kad numatytasis HighWaterMark vertė (kurią galima tinkinti) yra 16 384 baitai. Tai reiškia, kad vienu metu šiame buferyje galite saugoti mažiau nei 16 384 baitus duomenų. Taigi, iki skaičiaus 2 915 (plius visi kableliai ir tarpai) reiškia didžiausią duomenų kiekį, kurį buferis gali saugoti vienu metu.

Buferio klaidos sprendimas yra naudoti srauto įvykį. Srautas susiduria su įvairiais įvykiais skirtinguose duomenų perdavimo proceso etapuose. The nusausinti įvykis yra tinkamas pasirinkimas šioje situacijoje.

Viduje writeData () aukščiau esanti funkcija, skambutis į WriteStream rašymas () funkcija grąžina true, jei duomenų dalis (arba vidinis buferis) yra žemiau HighWaterMark vertė. Tai rodo, kad programa gali siųsti daugiau duomenų į srautą. Tačiau kai tik rašyti () funkcija grąžina false, ciklas nutrūksta, nes reikia ištuštinti buferį.

myWriteStream.on('drain', () => {
console.log("a drain has occurred...");
writeData();
});

Įdėjus nusausinti įvykio kodas aukščiau į anoniminę funkciją ištuštins „WriteStream“ buferis kai jis veikia. Tada jis primena writeData () metodą, kad galėtų toliau rašyti duomenis. Paleidus atnaujintą programą bus pateikta tokia išvestis:

Turėtumėte atkreipti dėmesį, kad programa turėjo nusausinti WriteStream buferis tris kartus jo vykdymo metu. Teksto faile taip pat buvo keletas pakeitimų:

Kaip sukurti ir naudoti skaitomą srautą

Norėdami nuskaityti duomenis, pirmiausia sukurkite skaitomą srautą naudodami fs.createReadStream() funkcija.

const {createReadStream} = require("fs");

(() => {
const file = "myFile.txt";
const myReadStream = createReadStream(file);

myReadStream.on("open", () => {
console.log(`The read stream has successfully opened ${file}.`);
});

myReadStream.on("data", chunk => {
console.log("The file contains the following data: " + chunk.toString());
});

myReadStream.on("close", () => {
console.log("The file has been successfully closed.");
});
})();

Aukščiau pateiktame scenarijuje naudojamas sukurtiReadStream() būdas pasiekti failą, kurį sukūrė ankstesnis kodas: myFile.txt. The sukurtiReadStream() funkcija priima failo kelią (kuris gali būti eilutės, buferio arba URL pavidalu) ir keletą pasirenkamų parinkčių kaip argumentus.

Anoniminėje funkcijoje yra keli svarbūs srauto įvykiai. Tačiau nėra jokių ženklų, kad nusausinti įvykis. Taip yra todėl, kad skaitomas srautas saugo duomenis tik tada, kai skambinate stream.push (gabalas) funkciją arba naudokite skaitomas įvykis.

The atviras įvykis suaktyvinamas, kai fs atidaro failą, iš kurio norite skaityti. Kai pridedate duomenis įvykį į netiesiogiai nenutrūkstamą srautą, tai priverčia srautą pereiti į tekėjimo režimą. Tai leidžia perduoti duomenis, kai tik jie tampa prieinami. Paleidus aukščiau pateiktą programą, gaunama tokia išvestis:

Kaip sukurti ir naudoti dvipusį srautą

Dvipusis srautas įgyvendina ir rašomą, ir skaitomą srauto sąsajas, todėl galite skaityti ir rašyti tokį srautą. Vienas iš pavyzdžių yra TCP lizdas, kurio kūrimas priklauso nuo tinklo modulio.

Paprastas būdas parodyti dvipusio srauto savybes yra sukurti TCP serverį ir klientą, kuris perduoda duomenis.

Server.js failas

const net = require('net');
const port = 5000;
const host = '127.0.0.1';

const server = net.createServer();

server.on('connection', (socket)=> {
console.log('Connection established from client.');

socket.on('data', (data) => {
console.log(data.toString());
});

socket.write("Hi client, I am server " + server.address().address);

socket.on('close', ()=> {
console.log('the socket is closed')
});
});

server.listen(port, host, () => {
console.log('TCP server is running on port: ' + port);
});

Klientas.js failas

const net = require('net');
const client = new net.Socket();
const port = 5000;
const host = '127.0.0.1';

client.connect(port, host, ()=> {
console.log("connected to server!");
client.write("Hi, I'm client " + client.address().address);
});

client.on('data', (data) => {
console.log(data.toString());
client.write("Goodbye");
client.end();
});

client.on('end', () => {
console.log('disconnected from server.');
});

Pastebėsite, kad tiek serverio, tiek kliento scenarijai bendravimui (duomenims perduoti ir gauti) naudoja skaitomą ir rašomą srautą. Natūralu, kad pirmiausia paleidžiama serverio programa ir pradedama klausytis ryšių. Kai tik paleidžiate klientą, jis prisijungia prie serverio naudodamas TCP prievado numerį.

Užmezgęs ryšį, klientas inicijuoja duomenų perdavimą rašydamas į serverį, naudodamas savo WriteStream. Serveris registruoja gautus duomenis į terminalą, tada įrašo duomenis naudodamas savo WriteStream. Galiausiai klientas registruoja gautus duomenis, įrašo papildomus duomenis ir atsijungia nuo serverio. Serveris lieka atviras kitiems klientams prisijungti.

Kaip sukurti ir naudoti transformavimo srautą

Transformavimo srautai yra dvipusiai srautai, kurių išvestis yra susijusi su įvestimi, bet skiriasi nuo jos. Node.js turi dviejų tipų transformavimo srautus: zlib ir kriptovaliutų srautus. Zlib srautas gali suspausti tekstinį failą ir išskleisti jį po failo perdavimo.

CompressFile.js programa

const zlib = require('zlib');
const { createReadStream, createWriteStream } = require('fs');

(() => {
const source = createReadStream('myFile.txt');
const destination = createWriteStream('myFile.txt.gz');

source.pipe(zlib.createGzip()).pipe(destination);
})();

Šis paprastas scenarijus paima originalų tekstinį failą, jį suglaudina ir išsaugo dabartiniame kataloge. Tai paprastas procesas dėl skaitomo srauto vamzdis () metodas. Srauto dujotiekiai pašalina buferių ir vamzdžių duomenų naudojimą tiesiai iš vieno srauto į kitą.

Tačiau prieš duomenims pasiekiant rašomąjį scenarijaus srautą, reikia šiek tiek apeiti naudojant zlib's createGzip() metodą. Šis metodas suglaudina failą ir grąžina naują Gzip objektą, kurį tada gauna rašymo srautas.

DecompressFile.js programa

const zlib = require('zlib'); 
const { createReadStream, createWriteStream } = require('fs');
 
(() => {
const source = createReadStream('myFile.txt.gz');
const destination = createWriteStream('myFile2.txt');

source.pipe(zlib.createUnzip()).pipe(destination);
})();

Šis aukščiau pateiktas scenarijus paima suspaustą failą ir jį išskleidžia. Jei atidarysite naują manoFailas2.txt failą, pamatysite, kad jame yra tokie patys duomenys kaip ir pradiniame faile:

Kodėl srautai yra svarbūs?

Srautai padidina duomenų perdavimo efektyvumą. Skaitomi ir rašomi srautai yra pagrindas, leidžiantis palaikyti ryšį tarp klientų ir serverių, taip pat suspausti ir perkelti didelius failus.

Srautai taip pat pagerina programavimo kalbų našumą. Be srautų duomenų perdavimo procesas tampa sudėtingesnis, todėl kūrėjams reikia daugiau rankinio įvesties, todėl atsiranda daugiau klaidų ir našumo problemų.