Come può NodeJS essere "non bloccante"?


14

Sto imparando NodeJS e volevo solo chiarire qualcosa. Finora, in numerosi tutorial e libri introduttivi, hanno descritto molto presto l'architettura "non bloccante" di Node - o piuttosto che è possibile (e raccomandato l'intero punto) codificare in modo non bloccante.

Quindi, per esempio, questo esempio è stato dato in un libro che sto leggendo di un modo asincrono per ottenere dati da un database.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Quello che succede (per quanto ho capito) è che Node effettua la chiamata al database, quindi continua a elaborare qualunque cosa possa essere successiva nello stack di chiamate. Quando la richiesta del database è completa, la variabile di dati nella funzione di richiamata anonima verrà popolata e tale funzione verrà aggiunta allo stack di chiamate (e successivamente eseguita quando Node arriva ad essa).

La mia domanda è: che cosa sta esattamente elaborando la richiesta del database? Sicuramente Node deve bloccare mentre lo fa? Cosa si occupa della richiesta del database? O se Node è in attesa di una richiesta HTTP GET asincrona a una risorsa esterna, cosa si occupa di quella richiesta che consente a Node di continuare a elaborare lo stack di chiamate e di essere "non bloccante"?

Risposte:


17

Quando Node.js è descritto come "non bloccante", ciò significa specificamente che il suo IO non è bloccante. Node usa libuv per gestire il proprio IO in modo indipendente dalla piattaforma. Su Windows, utilizza porte di completamento IO, su Unix, utilizza epoll / kqueue / select / etc. Quindi, effettua una richiesta IO non bloccante (che può avere un monitoraggio dei thread in background, ma questo non è mai esposto a JavaScript) e, di conseguenza, lo mette in coda all'interno del ciclo degli eventi che chiama il callback JavaScript sul main (leggi: solo) thread JavaScript.

Per i database, dipende da come viene scritta la libreria. Se utilizza HTTP per comunicare (come fanno alcuni database NoSQL), potrebbe essere facilmente scritto in puro JavaScript utilizzando la httplibreria di nodi standard . Se lo fa in un altro modo, beh, dipende dalla biblioteca. Potrebbe essere scritto in C / C ++ e utilizzare i thread in background fintanto che l'astrazione non è mai esposta al JavaScript.

Per quanto riguarda la tua domanda su cosa sta "elaborando" la richiesta del database, idealmente tutto ciò che dovrebbe essere fatto è inviare un semplice messaggio a una libreria (ad esempio un'istruzione SQL o qualche altra query o una richiesta di connessione), e a quel punto il tuo JavaScript continua a soffocare. Quando la libreria è pronta a rispedire un messaggio, invia un messaggio alla coda degli eventi del nodo che esegue il callback, consentendo l'esecuzione di quel frammento di codice.


C'è il netpacchetto quando http non è disponibile.
Florian Margaine,

Dettagli che potrebbero aiutare. Il nodo sfrutta il motore V8 JS. Una delle migliori funzionalità di V8 è la facilità di associare i processi C / C ++ alle chiamate JS. Le funzioni JavaScript stanno bloccando, ma tutto ciò che una funzione fa è chiamare qualcosa che non si blocca. Quindi un'altra funzione JS risponde al termine di tale processo. Le funzioni JS che si bloccano a vicenda significano che non avrai mai due cose che provano a fare qualcosa come programmare una scrittura nello stesso percorso di file allo stesso tempo, dove presumo che il multi-thread debba essere gestito. È sempre chiaro quale richiesta è arrivata per prima allo scopo di mettere in coda le cose.
Erik Reppen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.