事件驱动(Event-Driven):
-
事件触发与监听:
-
在Node.js中,程序的执行是由事件的发生来触发的。通过
EventEmitter
类,我们可以创建对象,绑定事件监听器,然后触发相应的事件。 -
示例:
javascriptconst EventEmitter = require('events'); const myEmitter = new EventEmitter(); myEmitter.on('customEvent', () => { console.log('Custom event occurred!'); }); myEmitter.emit('customEvent');
-
-
回调函数的角色:
-
回调函数是事件的处理器,它会在事件发生时执行。这样的设计使得程序能够在等待某些操作完成的同时执行其他任务,而不会阻塞整个应用程序。
-
示例:
javascriptconst fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); });
-
非阻塞I/O(Non-Blocking I/O):
-
异步I/O操作:
-
Node.js通过使用异步I/O接口来处理文件读写、网络请求等操作。这意味着在执行一个I/O操作时,程序不会等待其完成,而是继续执行后续代码。
-
示例:
javascriptconst fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); });
-
-
事件循环(Event Loop):
-
事件循环是Node.js的核心,负责监听事件队列并执行相应的回调函数。这保证了在异步I/O操作进行的同时,程序能够继续响应其他事件。
-
示例:
javascriptconst start = Date.now(); setTimeout(() => { console.log('Timeout callback executed after', Date.now() - start, 'milliseconds'); }, 1000); setImmediate(() => { console.log('Immediate callback executed after', Date.now() - start, 'milliseconds'); });
-
通过这种方式,Node.js在事件驱动和非阻塞I/O的基础上,使得程序更具响应性,能够更高效地处理大量并发操作,提高了应用程序的性能。
例子
事件驱动(Event-Driven):
-
事件就是一种信号:
- 想象一下你去咖啡店等咖啡,当你的咖啡好了,服务员会叫你的名字。这个"叫名字"的动作就是一个事件,你的名字是信号。
-
回调函数就像接电话:
- 你不需要一直等在柜台前,只要你的咖啡好了,服务员就会用你的名字呼叫你。在编程中,这种等待的工作就由回调函数来完成。
非阻塞I/O(Non-Blocking I/O):
-
异步就是同时做多件事:
- 想象你在等电梯的时候,不需要一直盯着电梯门。你可以边等电梯边玩手机,等电梯好了,手机不会因此停止工作。在编程中,异步操作就是允许程序同时执行多个任务。
-
事件循环就像多任务经理:
- 把事件循环想象成一个多任务经理,负责调度各种任务。你告诉经理你要等电梯,然后就可以自由去做其他事情。当电梯好了,经理会通知你。
通过这样的比喻,事件驱动就像等咖啡和接电话一样,而非阻塞I/O就像等电梯和同时做多件事一样。这样的编程方式使得程序更加灵活,能够更高效地完成多个任务。