面试题答案
一键面试- 事件传播顺序:
- 在 Node.js 的
EventEmitter
中,当多个监听器依次处理同一事件时,事件传播顺序是按照监听器添加的顺序执行。也就是说,先通过on
或addListener
方法添加的监听器会先被调用。例如:
const EventEmitter = require('events'); const emitter = new EventEmitter(); emitter.on('test', () => { console.log('First listener'); }); emitter.on('test', () => { console.log('Second listener'); }); emitter.emit('test'); // 输出: // First listener // Second listener
- 在 Node.js 的
- 监听器抛出异常时的处理:
- 当某个监听器函数执行过程中抛出异常时,Node.js 的
EventEmitter
并不会自动捕获这个异常。这意味着如果没有手动处理,异常会向上冒泡,有可能导致程序崩溃。例如:
const EventEmitter = require('events'); const emitter = new EventEmitter(); emitter.on('test', () => { throw new Error('Some error'); }); emitter.emit('test'); // 会抛出异常,导致程序崩溃
- 当某个监听器函数执行过程中抛出异常时,Node.js 的
- 确保异常不导致程序崩溃及合理错误处理:
- 方法一:在监听器内部捕获异常:
- 可以在每个监听器函数内部使用
try - catch
块来捕获异常,这样就可以避免异常导致程序崩溃。例如:
const EventEmitter = require('events'); const emitter = new EventEmitter(); emitter.on('test', () => { try { throw new Error('Some error'); } catch (err) { console.error('Caught in listener:', err.message); } }); emitter.emit('test'); // 输出: Caught in listener: Some error
- 可以在每个监听器函数内部使用
- 方法二:使用
error
事件:EventEmitter
有一个特殊的error
事件。如果在EventEmitter
实例上添加了error
事件监听器,当任何监听器抛出未捕获的异常时,error
事件监听器会被调用。例如:
const EventEmitter = require('events'); const emitter = new EventEmitter(); emitter.on('error', (err) => { console.error('Caught by error event:', err.message); }); emitter.on('test', () => { throw new Error('Some error'); }); emitter.emit('test'); // 输出: Caught by error event: Some error
- 方法三:使用 domain(Node.js v0.8 - v14,已弃用):
- 在 Node.js 的早期版本(v0.8 - v14)中,可以使用
domain
模块来捕获多个异步操作中的未捕获异常。不过domain
模块已被弃用,不推荐在新代码中使用。例如:
const EventEmitter = require('events'); const Domain = require('domain'); const domain = Domain.create(); domain.on('error', (err) => { console.error('Caught by domain:', err.message); }); domain.run(() => { const emitter = new EventEmitter(); emitter.on('test', () => { throw new Error('Some error'); }); emitter.emit('test'); }); // 输出: Caught by domain: Some error
- 在 Node.js 的早期版本(v0.8 - v14)中,可以使用
- 方法一:在监听器内部捕获异常: