在 Node.js 和许多 JavaScript 环境中,EventEmitter
是一个非常重要的类,用于处理事件驱动编程。EventEmitter
是一个能够发射(emit)和监听(on)事件的对象。它常用于创建和处理事件机制,使得程序中的不同部分能够相互通信。
示例代码
假设有一个 FileManager
类,它继承自 EventEmitter
,并在添加文件时发射一个事件:
const EventEmitter = require ( 'events' ) ;
class FileManager extends EventEmitter {
addFile ( file ) {
console. log ( ` File added: ${ file} ` ) ;
this . emit ( 'files-added' , file) ;
}
}
const fileManager = new FileManager ( ) ;
fileManager. on ( 'files-added' , ( file ) => {
console. log ( ` Listener received file: ${ file} ` ) ;
} ) ;
fileManager. addFile ( 'example.txt' ) ;
在这个示例中,当 addFile
方法被调用时,它不仅会添加文件,还会发射一个 'files-added'
事件。注册到这个事件上的监听器会被触发,并处理相关的逻辑。
PS C:\Users\kingchuxing\Documents\ELECTRON\my-electron-app> node .\test.js
File added: example.txt
Listener received file: example.txt
用EventEmitter实现的库:menubar
var menubar = new events.EventEmitter() // 创建一个新的 EventEmitter 实例,并赋值给变量 menubar
menubar.app = app // 将 app 对象赋值给 menubar 的 app 属性
if (app.isReady()) { // 检查应用程序是否已经准备好
appReady() // 如果应用程序已经准备好,调用 appReady 函数
} else {
// 如果应用程序尚未准备好,注册一个监听器
// 当应用程序发出 'ready' 事件时,调用 appReady 函数
app.on('ready', appReady)
}
var menubar = require('menubar')
var mb = menubar()
mb.on('ready', function ready () {
console.log('app is ready')
// your app code here
})
使用EventEmitter的例子
Node.js的EventEmitter和IPC机制可以结合使用来实现跨进程的事件驱动通信。事件驱动模型可以帮助处理进程间传递的异步消息和事件,使得应用程序的设计更加灵活和响应迅速。
const {ipcMain} = require('electron'); // electron
const logger = require('electron-log'); // electron
const menubar = require('menubar'); // electron
const fs = require('fs-extra'); // 文件处理
// 事件驱动编程类
const MyEventEmitter = require('./classes/ MyEventEmitter.js');
// 资源地址
const { ICON_PATH,INDEX_PATH } = require('./respath');
// IPC(进程间通信)标签
// 与MyEventEmitter绑定的:this.emit(IPC_EVENT_STATE_CHANGE, this.**)
// 与前端ui绑定的:比如menu.append(new MenuItem({ label: 'Quit(界面显示项)', click: () => ipcRenderer.send(IPC_EVENT_QUIT_APP) }));
const {
IPC_EVENT_STATE_CHANGE,IPC_EVENT_FILES_ADDED,
IPC_EVENT_QUIT_APP,} = require('../ipds/constants');
const myEventEmitter = new MyEventEmitter();
const mb = menubar({
icon: ICON_PATH,
index: INDEX_PATH,// index.html的路径
preloadWindow: true,
alwaysOnTop: false,
width: 350,
height: 400,
});
// Menubar的IPC调用
mb.on('ready', () => {
setTimeout(() => {mb.showWindow(); }, 1000); // 在显示窗口之前添加一个短暂的延迟(1 秒),可以避免这种闪烁或关闭现象。
});
mb.on('show', () => {
logger.error('[ipcMain] show方法调用');
});
// yMEventEmitter的IPC调用
myEventEmitter.on(IPC_EVENT_STATE_CHANGE, () => {
});
myEventEmitter.on(IPC_EVENT_FILES_ADDED, () => {
logger.info('[myEventEmitter] files-added');
});
// ipcMain:Inter Process (Main <-> Render) Communication
ipcMain.on(IPC_EVENT_QUIT_APP, () => {
mb.app.quit();
myEventEmitter.quit();
});
CG
进程间通信 (IPC) 是在 Electron 中构建功能丰富的桌面应用程序的关键部分。由于主进程和渲染进程在 Electron 的进程模型中具有不同的职责,因此 IPC 是执行许多常见任务的唯一方式,例如从 UI 调用本机 API 或从本机菜单触发 Web 内容的更改。 IPC 指 处理器间调用 (Inter-Processor Call),而不是其他操作系统中所指的 进程间通信 (Inter-Process Communication)