📜  Node.js 中的回调和事件

📅  最后修改于: 2022-05-13 01:56:49.538000             🧑  作者: Mango

Node.js 中的回调和事件

在本文中,我们将学习 Nodejs 中的回调和事件。回调和事件都是 Nodejs 的重要概念。让我们先了解一下回调。

回调概念

回调是在完成特定任务时自动调用的函数。回调函数允许程序运行其他代码,直到某个任务没有完成。回调函数在 nodeJS 中被大量使用。回调函数允许您执行大量可由操作系统处理的 I/O 操作,而无需等待任何 I/O 操作完成。它使 nodeJS 具有高度可扩展性。例如:在 Node.js 中,当一个函数开始读取文件时,显然需要一些时间,所以无需等待该函数完成,它立即将控制权返回给执行环境,以便执行后续指令。一旦文件 I/O 完成,回调函数将被自动调用,因此不会等待或阻塞文件 I/O。

注意:这些天回调函数正在被 async/await 取代。

语法:让我们看看回调函数的语法。

const fs = require("fs");

fs.readFile("file_path", "utf8", function(err, data) {
   if(err) {
       // Handle the error  
   } else {
       // Process the file text given with data
   }
});

示例 1:在 Node.js 中同步读取文件的代码。使用以下文本创建文本文件 input.txt:

Welcome to GFG.
Learn NodeJS with GeeksforGeeks

现在,使用以下代码创建一个名为 main.js 的 JavaScript 文件。

main.js
var fs = require("fs");
var filedata = fs.readFileSync('input.txt');
console.log(filedata.toString());
console.log("End of Program execution");


main.js
var fs = require("fs");    
fs.readFile('input.txt', function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});
console.log("End of Program execution");


main.js
const EventEmitter = require('events');
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Create an event handler:
var EventHandler = function () {
  console.log('Learn nodejs!');
}
  
// Assign the event handler to an event:
eventEmitter.on('event1', EventHandler);
  
// Fire the 'scream' event:
eventEmitter.emit('event1');


main.js
// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances
var eventEmitter = new EventEmitter();
  
// Register to newListener
eventEmitter.on( 'newListener', (event, listener) => {
    console.log(`The listener is added to ${event}`);
});
  
// Register to removeListener
eventEmitter.on( 'removeListener', (event, listener) => {
    console.log(`The listener is removed from ${event}`);
});
  
// Declaring listener fun1 to myEvent1
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
  
// Declaring listener fun2 to myEvent2
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Listening to myEvent with fun1 and fun2
eventEmitter.on('myEvent', fun1);
eventEmitter.on('myEvent', fun2);
  
// Removing listener
eventEmitter.off('myEvent', fun1);
  
// Triggering myEvent
eventEmitter.emit('myEvent', 'Event occurred');


现在运行 main.js 以使用以下命令查看结果:

node main.js

说明:在这个例子中,我们有一个 nodeJS 的 fs 模块,它提供了文件 I/O 操作的功能。在 readFileSync()函数的帮助下,我们可以在这里使用同步方法,这也称为阻塞函数,因为它先等待每条指令完成,然后再执行下一条。因此,在这个例子中,函数会阻塞程序,直到它读取文件,然后继续程序结束。

输出:

GFG

示例 2:在 Node.js 中异步读取文件的代码。保持“input.txt”文件与以前相同。这是 main.js 的代码:

main.js

var fs = require("fs");    
fs.readFile('input.txt', function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});
console.log("End of Program execution");

现在运行 main.js 以使用以下命令查看结果:

node main.js

说明:借助 readFile()函数,我们可以在这里使用异步方法,也称为非阻塞函数,因为它从不等待每条指令完成,而是在第一次执行时自行执行所有操作.因此在本例中,函数在后台运行,控制权返回到下一条指令。当后台任务完成时回调函数被调用。

输出:

GFG

活动

计算机上的每个动作都称为一个事件。在 nodeJS 中,对象可以触发事件。根据 Node.js 的官方文档,它是一个异步事件驱动的 JavaScript 运行时。 Node.js 具有可以执行异步任务的事件驱动架构。 Node.js 有一个“事件”模块,它发出命名事件,这些事件可以导致调用相应的函数或回调。 Functions(Callbacks) 侦听或订阅要发生的特定事件,当该事件触发时,订阅该事件的所有回调都会按照注册的顺序一一触发。

EventEmmitter 类:所有发出事件的对象都是 EventEmitter 类的实例。可以在 EventEmitter 的帮助下发出或监听事件。

句法:

const EventEmitter=require('events');
var eventEmitter=new EventEmitter();

下表列出了 EventEmitter 类的所有重要方法:

EventEmitter MethodsDescription
eventEmitter.addListener(event, listener) &&
eventEmitter.on(event, listener)
eventEmmitter.on(event, listener) and eventEmitter.addListener(event, listener) are pretty much similar. It adds the listener at the end of the listener’s array for the specified event. Multiple calls to the same event and listener will add the listener multiple times and correspondingly fire multiple times. Both functions return emitter, so calls can be chained.
eventEmitter.once(event, listener)It fires at most once for a particular event and will be removed from listeners array after it has listened once. Returns emitter, so calls can be chained.
eventEmitter.emit(event, [arg1], [arg2], […])Every event is named event in nodeJS. We can trigger an event by emit(event, [arg1], [arg2], […]) function. We can pass an arbitrary set of arguments to the listener functions.
eventEmitter.removeListener(event, listener)It takes two argument event and listener and removes that listener from the listener’s array that is subscribed to that event
eventEmitter.removeAllListeners() It removes all the listeners from the array who are subscribed to the mentioned event.
eventEmitter.getMaxListeners(n)It will return the max listeners value set by setMaxListeners() or default value 10.
EventEmitter.defaultMaxListenersBy default, a maximum of 10 listeners can be registered for any single event. To change the default value for all EventEmitter instances this property can be used.
eventEmitter.listeners(event) It returns an array of listeners for the specified event.
eventEmitter.listenerCount() It returns the number of listeners listening to the specified event.
eventEmitter.prependOnceListener()It will add the one-time listener to the beginning of the array.
eventEmitter.prependListener()It will add the listener to the beginning of the array.

示例1:创建简单事件程序的代码:

main.js

const EventEmitter = require('events');
// Initializing event emitter instances 
var eventEmitter = new EventEmitter();
  
// Create an event handler:
var EventHandler = function () {
  console.log('Learn nodejs!');
}
  
// Assign the event handler to an event:
eventEmitter.on('event1', EventHandler);
  
// Fire the 'scream' event:
eventEmitter.emit('event1');

现在运行 main.js 以使用以下命令查看结果:

node main.js

输出:

示例 2:此示例显示了侦听器的创建和删除。 EventEmitter 实例将发出自己的“newListener”事件。删除侦听器后会发出“removeListener”事件。

main.js

// Importing events
const EventEmitter = require('events');
  
// Initializing event emitter instances
var eventEmitter = new EventEmitter();
  
// Register to newListener
eventEmitter.on( 'newListener', (event, listener) => {
    console.log(`The listener is added to ${event}`);
});
  
// Register to removeListener
eventEmitter.on( 'removeListener', (event, listener) => {
    console.log(`The listener is removed from ${event}`);
});
  
// Declaring listener fun1 to myEvent1
var fun1 = (msg) => {
    console.log("Message from fun1: " + msg);
};
  
// Declaring listener fun2 to myEvent2
var fun2 = (msg) => {
    console.log("Message from fun2: " + msg);
};
  
// Listening to myEvent with fun1 and fun2
eventEmitter.on('myEvent', fun1);
eventEmitter.on('myEvent', fun2);
  
// Removing listener
eventEmitter.off('myEvent', fun1);
  
// Triggering myEvent
eventEmitter.emit('myEvent', 'Event occurred');

现在运行 main.js 以使用以下命令查看结果:

node main.js

输出: