事件与函数的区别是什么?

11

我刚接触Node,我很难理解事件和函数之间的主要区别。它们都需要被触发,那么既然我们必须要触发它们,为什么还需要事件呢?

与触发函数有何不同?

示例代码:

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

eventEmitter.on('event1', function () {
    console.log('Event 1 executed.');
    eventEmitter.emit('event2');
});

eventEmitter.on('event2', function() {
    console.log('Event 2 executed.');
});

eventEmitter.emit('event1');
console.log('Program Ended.');

我们可以通过函数实现相同的结果,对吧?

我确定这在Node中非常重要(否则它不会存在,哈哈),但我很难理解。

感谢您的帮助!:)


1
一个函数像方法一样通过传递参数来调用…(…)。它不是“触发”的。 - Bergi
2
你如何通过函数来实现“相同的结果”?请注意,您已经在 Event Emitter 解决方案中使用函数作为事件处理程序。 - Bergi
为了达到相同的结果,而不是通过监听器触发事件,只需手动调用您想要运行的所有函数。@Bergi - Frank
4个回答

14

事件处理异步操作,与函数并不相关,不能互换使用。

eventEmitter.on 是一个函数,它接受两个参数:事件名称和在事件发生时要执行的回调函数。

eventEmitter.on(evt, callback)

无法确定事件何时被触发,因此需要提供回调函数在事件发生时被执行。

在您的示例中,您控制事件何时被触发,这与实际使用场景不同。在现实世界中,您可能有一个服务器正在侦听连接,可能随时连接。

server.listen('9000', function(){
    console.log('Server started');
});

server.on('connection', function(client){
    console.log('New client connected');
    doSomethingWithClient(client);
});

//series of synchronous events
function doSomethingWithClient(client){
    //something with client
}

对于server.listen,服务器不会立即启动,只有在准备就绪后才会调用回调函数。

server.on('connection')监听客户端连接,它们可以随时到来。当连接发生时触发该事件,导致回调函数运行。

然后是doSomethingWithClient,这只是一个在客户端连接发生时执行一组同步操作的函数。


非常有帮助。谢谢! - Ariel Weinberger
2
我也在努力理解这个问题。 好的,针对你代码中的示例:server.on('connection', function(client){ console.log('New client connected'); doSomethingWithClient(client); });但是为了执行这段代码,需要有一些人调用 event.emit('connection', client) 对吧? 那么如果调用一个函数:function connection(client){...} 与之有何区别呢? - Arthur Mastropietro

1

在Web服务器代码中有一些事件非常有用(这些事件在端口上活动),但是在普通脚本中,事件的行为与函数相同,因为只要端口处于活动状态,事件将持续活动并监听请求。因此,如果我们使用函数,函数将仅在运行.js文件时运行一次,因此函数无法捕获传入的请求并作出响应。

示例

在此代码中,如果您查看下面函数dummy_func()的输出,则会立即触发该函数,并且仅一次输出语句ConditionReport: A client Connected: 0,但是当我在浏览器中打开http://localhost:58080并再次在另一个选项卡中打开时,EventReport: A client Connected:才会被打印出来,如果我再次打开相同的http://localhost:58080,则再次打印EventReport: A client Connected: 3

const express = require('express');
const app = express();
const path = require('path');
const PORT = process.env.PORT || 58080;

// Load all static html files in the directory, here index.html file open as default at http://localhost:58080/ but to load html like Resume.html we should call complete http://localhost:58080/Resume.html
app.use(express.static(path.join(__dirname)));

// Configure Port
var server_object=app.listen(PORT, () => console.log("Server listening on port " + PORT));

//Possible incoming Events
var incoming_events=server_object.eventNames()
console.log("\nserver_object:", incoming_events);

//On Event
var i=0
server_object.on('connection',()=>{
    i=i+1
    console.log("\nEventReport: A client Connected:",i);
});

//Using if condition instead of Event
function dummy_func(j){
    console.log("\nConditionReport: A client Connected:",j,"\n");
}

var j=0
if (incoming_events.includes('connection')){
    dummy_func(j)
    j=j+1
}

输出:

stataraju@statara-ltm7wjr Example2 % node index.js

server_object: [ 'request', 'connection', 'listening' ]

ConditionReport: A client Connected: 0 

Server listening on port 58080

EventReport: A client Connected: 1

EventReport: A client Connected: 2

EventReport: A client Connected: 3

如果您理解上述内容,那么下一个问题就是为什么我不使用HTTP+函数来代替事件,例如通过HTTP帮助匹配路径并运行函数 :) 答案是,如果需要对多个路径执行相同的操作/函数,并且我们不确定哪个路径会触发操作/函数,则事件非常有用:https://dev59.com/0FQI5IYBdhLWcg3w-Qli - sudhir tataraju

0

我认为我看到的最大区别是事件发射器可以触发多个正在监听的事件,而仅调用函数只会触发一件事情。

例如,您可以在游戏中拥有许多对象,它们都在等待一个步骤事件来增加它们的动画。

但是它们非常难以调试,所以我更愿意使用函数。


我可以同时调用多个函数,这不是事件的专属权限。 - choxsword
是的,步进事件可以触发函数。现代技术很多都在试图让函数更抽象化。对我来说,类只是让函数更难调试。只需拥有一个包含所有连接函数的文件,为什么要创建一个类呢?但我只开发小型应用程序。大型应用程序可能会更有用。 - Frank

-1

事件是在工具中使用的标识符(.on().emit()等),用于设置和执行回调。函数是可重复使用的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接