Tokovi v Node.js so lahko zapleteni, vendar si je vredno vzeti čas in jih razumeti.

Ključni zaključki

  • Tokovi v Node.js so temeljno orodje za obdelavo in prenos podatkov, zaradi česar so idealni za aplikacije v realnem času in na dogodke.
  • Za ustvarjanje zapisljivega toka v Node.js lahko uporabite funkcijo createWriteStream() modula fs, ki zapisuje podatke na določeno lokacijo.
  • Berljivi, zapisljivi, dvostranski in transformacijski so štiri vrste tokov v Node.js, od katerih ima vsak svoj primer uporabe in funkcionalnost.

Tok je temeljno programsko orodje, ki se ukvarja s pretokom podatkov. V svojem jedru tok običajno predstavlja zaporedni prenos bajtov iz ene točke v drugo. Uradna dokumentacija Node.js definira tok kot abstrakten vmesnik, ki ga lahko uporabite za delo s podatki.

Prenos podatkov v računalnik ali prek omrežja je idealna uporaba toka.

Tokovi v Node.js

Tokovi so igrali bistveno vlogo pri uspehu Node.js. Idealni so za obdelavo podatkov v realnem času in aplikacije, ki jih poganjajo dogodki, kar sta dve pomembni lastnosti izvajalnega okolja Node.js.

instagram viewer

Če želite ustvariti nov tok v Node.js, boste morali uporabiti API toka, ki deluje izključno z nizi in Podatki medpomnilnika Node.js. Node.js ima štiri vrste tokov: zapisljive, berljive, dvostranske in transformacijske.

Kako ustvariti in uporabljati zapisljiv tok

Zapisljivi tok vam omogoča pisanje ali pošiljanje podatkov na določeno lokacijo. Modul fs (datotečni sistem) ima razred WriteStream, ki ga lahko uporabite za ustvarjanje novega toka z fs.createWriteStream() funkcijo. Ta funkcija sprejme pot do datoteke, v katero želite zapisati podatke, kot tudi neobvezen niz možnosti.

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();
})();

Ta koda uvozi createWriteStream() funkcijo, ki funkcijo anonimne puščice nato uporabi za ustvarjanje toka, ki zapisuje podatke v myFile.txt. Anonimna funkcija vsebuje notranjo funkcijo, imenovano writeData() ki piše podatke.

The createWriteStream() funkcija deluje z medpomnilnikom za pisanje zbirke števil (0–9.999) v ciljno datoteko. Vendar ko zaženete zgornji skript, ustvari datoteko v istem imeniku, ki vsebuje naslednje podatke:

Trenutna zbirka številk se konča pri 2.915, vendar bi morala vključevati številke do 9.999. Do tega neskladja pride, ker vsak WriteStream uporablja vmesni pomnilnik, ki shranjuje določeno količino podatkov hkrati. Če želite izvedeti, kakšna je ta privzeta vrednost, se boste morali posvetovati z highWaterMark možnost.

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

Dodajanje zgornje vrstice kode anonimni funkciji bo v terminalu ustvarilo naslednji izhod:

Izhod terminala kaže, da je privzeto highWaterMark vrednost (ki jo je mogoče prilagoditi) je 16.384 bajtov. To pomeni, da lahko v tem medpomnilniku hkrati shranite le manj kot 16.384 bajtov podatkov. Torej do številke 2.915 (plus vse vejice in presledki) predstavlja največjo količino podatkov, ki jih medpomnilnik lahko shrani naenkrat.

Rešitev napake medpomnilnika je uporaba tokovnega dogodka. Tok naleti na različne dogodke v različnih fazah procesa prenosa podatkov. The odtok dogodek je primerna možnost za to situacijo.

V writeData() funkcijo zgoraj, klic na WriteStream's write() funkcija vrne true, če je kos podatkov (ali notranji medpomnilnik) pod highWaterMark vrednost. To pomeni, da lahko aplikacija pošlje več podatkov v tok. Vendar pa takoj, ko pisati() funkcija vrne false zanka se prekine, ker morate izprazniti medpomnilnik.

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

Vstavljanje odtok zgornja koda dogodka v anonimno funkcijo bo izpraznila Medpomnilnik WriteStream ko je na zmogljivosti. Nato se spomni na writeData() metodo, tako da lahko nadaljuje s pisanjem podatkov. Zagon posodobljene aplikacije bo proizvedel naslednje rezultate:

Upoštevati morate, da je morala aplikacija izprazniti Medpomnilnik WriteStream trikrat med njegovo izvedbo. Tudi besedilna datoteka je doživela nekaj sprememb:

Kako ustvariti in uporabljati berljiv tok

Za branje podatkov začnite z ustvarjanjem berljivega toka z uporabo fs.createReadStream() funkcijo.

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.");
});
})();

Zgornji skript uporablja createReadStream() metoda za dostop do datoteke, ki jo je ustvarila prejšnja koda: myFile.txt. The createReadStream() funkcija sprejme pot do datoteke (ki je lahko v obliki niza, medpomnilnika ali URL-ja) in več izbirnih možnosti kot argumente.

V anonimni funkciji je več pomembnih tokovnih dogodkov. Vendar pa ni nobenega znaka odtok dogodek. To je zato, ker berljiv tok shrani podatke v medpomnilnik le, ko pokličete stream.push (kos) funkcijo ali uporabite berljivo dogodek.

The odprto dogodek se sproži, ko fs odpre datoteko, iz katere želite brati. Ko pritrdite podatke dogodek v implicitno neprekinjen tok, povzroči, da tok preide v tekoči način. To omogoča prenos podatkov takoj, ko so na voljo. Zagon zgornje aplikacije ustvari naslednje rezultate:

Kako ustvariti in uporabljati dvostranski tok

Dvostranski tok izvaja vmesnike tokov za pisanje in branje, tako da lahko tak tok berete in pišete vanj. En primer je vtičnica TCP, ki se pri ustvarjanju zanaša na omrežni modul.

Preprost način za prikaz lastnosti dupleksnega toka je ustvarjanje strežnika TCP in odjemalca, ki prenaša podatke.

Datoteka server.js

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);
});

Datoteka client.js

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.');
});

Opazili boste, da tako strežniški kot odjemalski skript uporabljata berljiv in zapisljiv tok za komunikacijo (prenos in prejemanje podatkov). Seveda se najprej zažene strežniška aplikacija in začne poslušati povezave. Takoj ko zaženete odjemalca, se poveže s strežnikom z uporabo številko vrat TCP.

Po vzpostavitvi povezave odjemalec sproži prenos podatkov s pisanjem na strežnik s svojim WriteStream. Strežnik zabeleži podatke, ki jih prejme v terminal, nato pa zapiše podatke s svojim WriteStream. Na koncu odjemalec zabeleži podatke, ki jih prejme, zapiše dodatne podatke in nato prekine povezavo s strežnikom. Strežnik ostane odprt za povezovanje drugih odjemalcev.

Kako ustvariti in uporabiti transformacijski tok

Pretvorbeni tokovi so dupleksni tokovi, v katerih je izhod povezan z vhodom, vendar drugačen od njega. Node.js ima dve vrsti transformacijskih tokov: zlib in kripto tokove. Tok zlib lahko stisne besedilno datoteko in jo nato razpakira po prenosu datoteke.

Aplikacija compressFile.js

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);
})();

Ta preprost skript vzame izvirno besedilno datoteko, jo stisne in shrani v trenutni imenik. To je preprost postopek zahvaljujoč berljivim tokovom cev() metoda. Pretočni cevovodi odstranijo uporabo medpomnilnikov in napeljejo podatke neposredno iz enega toka v drugega.

Toda preden podatki dosežejo zapisljivi tok v skriptu, je potreben majhen ovinek prek zlibove metode createGzip(). Ta metoda stisne datoteko in vrne nov objekt Gzip, ki ga nato prejme pisalni tok.

Aplikacija decompressFile.js

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);
})();

Ta zgornji skript vzame stisnjeno datoteko in jo razpakira. Če odprete novo mojaDatoteka2.txt datoteko, boste videli, da vsebuje iste podatke kot izvirna datoteka:

Zakaj so tokovi pomembni?

Tokovi povečajo učinkovitost prenosa podatkov. Berljivi in ​​zapisljivi tokovi služijo kot temelj, ki omogoča komunikacijo med odjemalci in strežniki ter stiskanje in prenos velikih datotek.

Tokovi tudi izboljšajo delovanje programskih jezikov. Brez tokov postane postopek prenosa podatkov bolj zapleten, saj od razvijalcev zahteva več ročnih vnosov, kar povzroči več napak in težav z zmogljivostjo.