本文目录导读:

浏览器环境 (JavaScript)
使用 CustomEvent API
// 创建自定义事件
class EventManager {
constructor() {
this.events = {};
}
// 注册事件监听
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
// 返回取消订阅函数
return () => {
this.events[eventName] = this.events[eventName].filter(cb => cb !== callback);
};
}
// 触发事件
emit(eventName, data) {
const callbacks = this.events[eventName];
if (callbacks) {
callbacks.forEach(callback => {
callback(data);
});
}
}
// 移除特定事件的所有监听
off(eventName) {
delete this.events[eventName];
}
}
// 使用示例
const eventBus = new EventManager();
// 注册回调
const unsubscribe = eventBus.on('userLogin', (userData) => {
console.log('用户登录:', userData);
// 执行自定义脚本
executeCustomScript(userData);
});
// 触发事件
eventBus.emit('userLogin', {
id: 1,
name: '张三',
timestamp: Date.now()
});
使用浏览器原生 CustomEvent
// 创建自定义事件
function createCustomEvent(eventName, detail) {
return new CustomEvent(eventName, {
detail: detail,
bubbles: true,
cancelable: true
});
}
// 监听事件
document.addEventListener('myCustomEvent', (event) => {
console.log('自定义事件触发:', event.detail);
executeScript(event.detail.script);
}, false);
// 触发事件
function triggerCustomEvent(scriptData) {
const event = createCustomEvent('myCustomEvent', {
source: 'user-action',
script: scriptData,
timestamp: Date.now()
});
document.dispatchEvent(event);
}
// 动态执行脚本
function executeScript(scriptContent) {
try {
// 方式1: 使用 eval
eval(scriptContent);
// 方式2: 创建 script 元素
const script = document.createElement('script');
script.textContent = scriptContent;
document.body.appendChild(script);
document.body.removeChild(script);
} catch (error) {
console.error('脚本执行失败:', error);
}
}
Node.js 环境
使用 EventEmitter
const EventEmitter = require('events');
const { exec } = require('child_process');
const fs = require('fs');
class ScriptEventHandler extends EventEmitter {
constructor() {
super();
this.scriptRegistry = new Map();
}
// 注册事件和对应的脚本
registerScript(eventName, scriptPath) {
if (!this.scriptRegistry.has(eventName)) {
this.scriptRegistry.set(eventName, []);
}
this.scriptRegistry.get(eventName).push(scriptPath);
// 自动绑定事件监听
this.on(eventName, async (data) => {
await this.executeScripts(eventName, data);
});
}
// 执行注册的脚本
async executeScripts(eventName, data) {
const scripts = this.scriptRegistry.get(eventName) || [];
for (const scriptPath of scripts) {
try {
if (scriptPath.endsWith('.js')) {
// 执行 JavaScript 文件
const script = require(scriptPath);
if (typeof script === 'function') {
await script(data);
}
} else if (scriptPath.endsWith('.sh') || scriptPath.endsWith('.bat')) {
// 执行 shell 脚本
await this.executeShellScript(scriptPath, data);
}
} catch (error) {
console.error(`脚本 ${scriptPath} 执行失败:`, error);
}
}
}
// 执行 shell 脚本
executeShellScript(scriptPath, data) {
return new Promise((resolve, reject) => {
const env = { ...process.env, EVENT_DATA: JSON.stringify(data) };
const child = exec(scriptPath, { env }, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
console.log(`脚本输出: ${stdout}`);
resolve(stdout);
});
});
}
// 触发事件
trigger(eventName, data) {
console.log(`事件 "${eventName}" 被触发`);
this.emit(eventName, data);
}
}
// 使用示例
const handler = new ScriptEventHandler();
// 注册脚本
handler.registerScript('fileChanged', './scripts/processFile.js');
handler.registerScript('fileChanged', './scripts/backup.sh');
handler.registerScript('error', './scripts/notifyAdmin.sh');
// 触发事件
handler.trigger('fileChanged', {
path: '/path/to/file.txt',
action: 'modified',
timestamp: Date.now()
});
基于配置文件的事件驱动系统
config.json
{
"events": [
{
"name": "user.register",
"scripts": [
{
"type": "javascript",
"path": "./scripts/welcomeEmail.js",
"async": true
},
{
"type": "shell",
"path": "./scripts/logRegistration.sh",
"params": ["username", "email"]
},
{
"type": "python",
"path": "./scripts/updateAnalytics.py",
"params": ["user_id"]
}
],
"conditions": {
"role": "user",
"verified": true
}
},
{
"name": "file.upload",
"scripts": [
{
"type": "javascript",
"code": "console.log('文件上传完成:', data.filename);"
},
{
"type": "shell",
"path": "./scripts/virusScan.sh",
"params": ["filepath"]
}
]
}
]
}
动态事件引擎实现
const fs = require('fs');
const path = require('path');
const { exec, spawn } = require('child_process');
const EventEmitter = require('events');
class DynamicEventEngine extends EventEmitter {
constructor(configPath) {
super();
this.config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
this.initialize();
}
initialize() {
this.config.events.forEach(eventConfig => {
this.on(eventConfig.name, async (data) => {
// 检查条件
if (this.checkConditions(eventConfig.conditions, data)) {
await this.executeScripts(eventConfig.scripts, data);
}
});
});
}
checkConditions(conditions, data) {
if (!conditions) return true;
return Object.entries(conditions).every(([key, value]) => {
if (typeof value === 'function') {
return value(data[key], data);
}
return data[key] === value;
});
}
async executeScripts(scripts, data) {
for (const scriptConfig of scripts) {
try {
await this.executeScript(scriptConfig, data);
} catch (error) {
console.error(`脚本执行失败:`, error);
this.emit('script.error', { scriptConfig, error, data });
}
}
}
async executeScript(scriptConfig, data) {
switch (scriptConfig.type) {
case 'javascript':
return this.executeJavaScript(scriptConfig, data);
case 'shell':
return this.executeShellScript(scriptConfig, data);
case 'python':
return this.executePythonScript(scriptConfig, data);
default:
throw new Error(`不支持的脚本类型: ${scriptConfig.type}`);
}
}
executeJavaScript(scriptConfig, data) {
return new Promise((resolve, reject) => {
try {
if (scriptConfig.path) {
const scriptModule = require(path.resolve(scriptConfig.path));
if (typeof scriptModule === 'function') {
resolve(scriptModule(data));
}
} else if (scriptConfig.code) {
const fn = new Function('data', scriptConfig.code);
resolve(fn(data));
}
} catch (error) {
reject(error);
}
});
}
executeShellScript(scriptConfig, data) {
return new Promise((resolve, reject) => {
const params = (scriptConfig.params || [])
.map(param => data[param])
.filter(p => p !== undefined);
const child = spawn(scriptConfig.path, params, {
env: { ...process.env, EVENT_DATA: JSON.stringify(data) }
});
let output = '';
child.stdout.on('data', (chunk) => { output += chunk; });
child.stderr.on('data', (chunk) => { output += chunk; });
child.on('close', (code) => {
if (code === 0) {
resolve(output);
} else {
reject(new Error(`脚本退出码: ${code}`));
}
});
});
}
executePythonScript(scriptConfig, data) {
return new Promise((resolve, reject) => {
const params = (scriptConfig.params || [])
.map(param => JSON.stringify(data[param]))
.filter(p => p !== undefined);
const child = spawn('python3', [
scriptConfig.path,
...params,
'--data', JSON.stringify(data)
]);
let output = '';
child.stdout.on('data', (chunk) => { output += chunk; });
child.on('close', (code) => {
if (code === 0) {
resolve(JSON.parse(output));
} else {
reject(new Error(`Python脚本退出码: ${code}`));
}
});
});
}
// 触发事件方法
trigger(eventName, data) {
console.log(`触发事件: ${eventName}`);
this.emit(eventName, data);
}
}
// 使用示例
const engine = new DynamicEventEngine('./config.json');
// 触发用户注册事件
engine.trigger('user.register', {
username: 'newuser',
email: 'user@example.com',
user_id: 12345,
role: 'user',
verified: true
});
// 触发文件上传事件
engine.trigger('file.upload', {
filename: 'document.pdf',
filepath: '/uploads/document.pdf',
size: 1024576,
type: 'application/pdf'
});
WebSocket 方式(实时事件触发)
// 服务器端 (Node.js)
const WebSocket = require('ws');
const http = require('http');
class WebSocketEventSystem {
constructor(port = 8080) {
this.server = http.createServer();
this.wss = new WebSocket.Server({ server: this.server });
this.clients = new Set();
this.scripts = new Map();
this.setupWebSocket();
this.server.listen(port);
}
setupWebSocket() {
this.wss.on('connection', (ws) => {
this.clients.add(ws);
ws.on('message', (message) => {
const data = JSON.parse(message);
this.handleMessage(ws, data);
});
ws.on('close', () => {
this.clients.delete(ws);
});
});
}
handleMessage(ws, data) {
switch (data.type) {
case 'register_script':
this.registerScript(data.event, data.script);
break;
case 'trigger_event':
this.triggerEvent(data.event, data.payload);
break;
case 'execute_callback':
this.executeCallback(data.callbackId, data.result);
break;
}
}
registerScript(eventName, script) {
if (!this.scripts.has(eventName)) {
this.scripts.set(eventName, []);
}
this.scripts.get(eventName).push(script);
}
async triggerEvent(eventName, payload) {
const scripts = this.scripts.get(eventName) || [];
// 广播事件给所有客户端
this.broadcast({
type: 'event_triggered',
event: eventName,
payload: payload
});
// 执行本地脚本
for (const script of scripts) {
await this.executeScript(script, payload);
}
}
executeScript(script, payload) {
return new Promise((resolve) => {
if (typeof script === 'function') {
resolve(script(payload));
} else if (typeof script === 'string') {
try {
const fn = new Function('payload', 'resolve', script);
fn(payload, resolve);
} catch (error) {
console.error('脚本执行错误:', error);
resolve(null);
}
}
});
}
broadcast(message) {
const data = JSON.stringify(message);
this.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
}
}
// 客户端 (浏览器)
class EventClient {
constructor(url = 'ws://localhost:8080') {
this.ws = new WebSocket(url);
this.callbacks = new Map();
this.callbackId = 0;
this.setup();
}
setup() {
this.ws.onopen = () => {
console.log('WebSocket 连接已建立');
};
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
this.handleServerMessage(data);
};
}
handleServerMessage(data) {
switch (data.type) {
case 'event_triggered':
// 事件被触发,执行回调
if (this.callbacks.has(data.event)) {
this.callbacks.get(data.event).forEach(callback => {
callback(data.payload);
});
}
break;
}
}
on(eventName, callback) {
if (!this.callbacks.has(eventName)) {
this.callbacks.set(eventName, []);
}
this.callbacks.get(eventName).push(callback);
// 通知服务器注册监听
this.send({
type: 'register_listener',
event: eventName
});
}
trigger(eventName, payload) {
this.send({
type: 'trigger_event',
event: eventName,
payload: payload
});
}
send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
}
}
}
// 使用示例
// 服务器端
const eventSystem = new WebSocketEventSystem(8080);
// 客户端
const client = new EventClient();
client.on('user_action', (data) => {
console.log('用户操作:', data);
// 执行自定义脚本
if (data.script) {
eval(data.script);
}
});
// 触发事件
client.trigger('user_action', {
type: 'click',
element: '#button',
script: 'alert("自定义脚本执行!")'
});
数据库驱动的事件系统
class DatabaseEventSystem {
constructor(db) {
this.db = db;
this.listeners = new Map();
this.setupDatabaseTriggers();
}
setupDatabaseTriggers() {
// 监听数据库变更
this.db.changes({
since: 'now',
live: true,
include_docs: true
}).on('change', (change) => {
this.handleDatabaseChange(change);
});
}
handleDatabaseChange(change) {
const eventName = `db.${change.doc.type}.${change.doc.action || 'modified'}`;
const data = change.doc;
// 执行绑定的脚本
this.executeEventScripts(eventName, data);
}
bindEvent(eventName, scriptConfig) {
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, []);
}
this.listeners.get(eventName).push(scriptConfig);
}
async executeEventScripts(eventName, data) {
const scripts = this.listeners.get(eventName) || [];
for (const script of scripts) {
await this.runScript(script, data);
}
}
async runScript(scriptConfig, data) {
// 实现脚本执行逻辑
// 可以支持不同的脚本类型
}
}
最佳实践建议
- 异步处理:对于耗时的脚本,使用异步执行
- 错误处理:添加 try-catch 和错误日志
- 安全考虑:
- 限制可执行的脚本类型
- 使用沙箱环境
- 验证脚本来源
- 性能优化:
- 使用事件队列
- 限制并发执行数
- 实现熔断机制
- 调试支持:
- 添加日志记录
- 实现事件追踪
- 提供测试工具
选择合适的实现方式取决于你的具体需求:是浏览器环境、Node.js 后端、还是跨平台的实时系统。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播