Diamo un'occhiata al secondo reclamo.
The JavaScript reactor pattern will always handle concurrency better than any multi-threaded application.
Per rispondere a questa affermazione, assumerò che la concorrenza in questo contesto equivalga alla scalabilità, poiché la scalabilità è una delle motivazioni principali alla base di Node.JS. La distinzione è sottile, ma significativa: ci sono molti modi per ottenere un'applicazione più scalabile; la concorrenza è a senso unico, ma ce ne sono altri. Assumerò anche che NodeJS implementa il pattern del reattore, anche se non lo descriverò in dettaglio qui.
Per scalabilità, intendo "la capacità di gestire quante più richieste simultanee possibili". Il modo in cui node.js esegue ciò è fornendo un ciclo di eventi . Il ciclo degli eventi accetta una richiesta dal client e quindi la consegna immediatamente a "qualche altro meccanismo" per l'elaborazione. Quindi restituisce il controllo al chiamante. Questo approccio asincrono consente a node.js di accettare molte richieste in un determinato intervallo di tempo e si differenzia da altre, più strategie sincrone , in cui il chiamante deve attendere il risultato prima di continuare . La quantità di elaborazione richiesta dal ciclo degli eventi è piuttosto ridotta, quindi è pronta (o quasi pronta) la maggior parte del tempo per accettare nuove richieste.
Cosa succede alle richieste una volta che vengono consegnate? Bene, ai fini della nostra discussione, questo è un dettaglio di implementazione. Una determinata richiesta potrebbe essere inserita in una propria discussione, oppure potrebbe essere accodata in un thread che contiene altre attività. Potrebbe essere consegnato a un servizio di Windows o addirittura inviato ad altri sistemi per l'adempimento.
La cosa importante da considerare è la scalabilità che il ciclo degli eventi fornisce rendendo l' accettazione di una richiesta impiega il minor tempo possibile. Questo non richiede un thread separato per ogni richiesta; tutto ciò di cui hai veramente bisogno sono due thread (uno per eseguire il ciclo degli eventi e l'altro per elaborare le richieste).
Naturalmente, se vuoi che la tua richiesta venga soddisfatta entro un ragionevole lasso di tempo, devi dare un po 'di potenza ai dettagli di implementazione che ho menzionato prima. Non c'è il pranzo gratis. Ma questo è un problema pratico diverso rispetto alla scalabilità che si pone assicurandosi che le richieste di un servizio vengano accettate rapidamente, anche se il rinvio dei risultati di tali richieste viene posticipato in un secondo momento.
Quindi quando qualcuno dice qualcosa come "il modello del reattore gestisce la concorrenza meglio di più thread", sono un po 'imprecisi. In generale, stanno confrontando tecniche asincrone con il multi-threading (la programmazione asincrona non richiede necessariamente nuovi thread). Il modo in cui direi è:
By using an event loop, you can abstract the acceptance of a request away from the fulfillment of a request, thereby improving scalability without incurring the unnecessary overhead of additional threads.
Ulteriori letture
Una rapida introduzione al funzionamento di Node.js
Supporto del ciclo degli eventi node.js
Reactor:
Un modello comportamentale oggettuale per
Demultiplexing e Dispatching Handles per eventi sincroni