На веб-сайте nodejs.org описано, что вместо порождения потоков (2 МБ на каждый поток!) Для каждого соединения сервер использует select (), epoll, kqueue или / dev / poll для ожидания готовности сокета к читай пиши. Именно этот метод позволяет узлу избежать порождения потока на соединение, а издержки связаны с выделением кучи дескриптора сокета для соединения. Эта деталь реализации в значительной степени скрыта от разработчиков, а API net.socket, предоставляемый средой выполнения, предоставляет все необходимое для использования этой функции, даже не задумываясь об этом.
Узел также предоставляет свой собственный API событий через events.EventEmitter. Многие объекты узлов реализуют события для предоставления асинхронного (неблокирующего) уведомления о событиях, что идеально подходит для операций ввода-вывода, которые в других языках, таких как PHP, являются синхронными (блокирующими) по умолчанию. В случае узла net.socket API события запускаются для нескольких методов API, связанных с сокетом ввода-вывода, а обратные вызовы, которые передаются параметром этим методам, запускаются при возникновении события. События могут иметь функции обратного вызова, связанные с ними различными способами, принятие функции обратного вызова в качестве параметра является лишь удобством для разработчика.
Наконец, не путайте события ОС с событиями nodejs. В случае сетевого API события ОС передаются во время выполнения nodejs, а события nodejs - это javascript.
Надеюсь, это поможет.