Node.js — это однопоточное приложение, но оно может поддерживать параллелизм посредством концепции событий и обратных вызовов . Каждый API Node.js является асинхронным и однопоточным, они используют вызовы асинхронных функций для обеспечения параллелизма. Узел использует шаблон наблюдателя. Поток узла хранит цикл событий и всякий раз, когда задача завершается, запускает соответствующее событие, которое сигнализирует о выполнении функции прослушивателя событий.
Событийное программирование
Node.js интенсивно использует события, и это также одна из причин того, что Node.js довольно быстр по сравнению с другими подобными технологиями. Как только Node запускает свой сервер, он просто инициирует свои переменные, объявляет функции и затем просто ожидает наступления события.
В приложении, управляемом событиями, обычно существует основной цикл, который прослушивает события, а затем запускает функцию обратного вызова при обнаружении одного из этих событий.
Хотя события выглядят очень похоже на обратные вызовы, разница заключается в том, что функции обратного вызова вызываются, когда асинхронная функция возвращает свой результат, тогда как обработка событий работает с шаблоном наблюдателя. Функции, которые слушают события, действуют как наблюдатели . Всякий раз, когда событие запускается, его функция слушателя начинает выполняться. Node.js имеет несколько встроенных событий, доступных через модуль событий и класс EventEmitter, которые используются для привязки событий и прослушивателей событий следующим образом:
// Import events module var events = require('events'); // Create an eventEmitter object var eventEmitter = new events.EventEmitter();
Ниже приведен синтаксис для привязки обработчика события к событию:
// Bind event and event handler as follows eventEmitter.on('eventName', eventHandler);
Мы можем запустить событие программно следующим образом:
// Fire an event eventEmitter.emit('eventName');
пример
Создайте js-файл с именем main.js со следующим кодом —
// Import events module var events = require('events'); // Create an eventEmitter object var eventEmitter = new events.EventEmitter(); // Create an event handler as follows var connectHandler = function connected() { console.log('connection succesful.'); // Fire the data_received event eventEmitter.emit('data_received'); } // Bind the connection event with the handler eventEmitter.on('connection', connectHandler); // Bind the data_received event with the anonymous function eventEmitter.on('data_received', function() { console.log('data received succesfully.'); }); // Fire the connection event eventEmitter.emit('connection'); console.log("Program Ended.");
Теперь давайте попробуем запустить вышеуказанную программу и проверить ее вывод:
$ node main.js
ЭТО должно дать следующий результат —
connection successful. data received successfully. Program Ended.
Как работают Node-приложения?
В Node Application любая асинхронная функция принимает обратный вызов в качестве последнего параметра, а функция обратного вызова принимает ошибку в качестве первого параметра. Давайте снова вернемся к предыдущему примеру. Создайте текстовый файл с именем input.txt со следующим содержанием.
Tutorials Point is giving self learning content to teach the world in simple and easy way!!!!!
Создайте js-файл с именем main.js, имеющий следующий код —
var fs = require("fs"); fs.readFile('input.txt', function (err, data) { if (err) { console.log(err.stack); return; } console.log(data.toString()); }); console.log("Program Ended");
Здесь fs.readFile () — это асинхронная функция, целью которой является чтение файла. Если во время операции чтения возникает ошибка, объект err будет содержать соответствующую ошибку, иначе данные будут содержать содержимое файла. readFile передает err и данные в функцию обратного вызова после завершения операции чтения, которая, наконец, печатает содержимое.