如何在Google Apps Script中创建、分发并处理自定义事件?
问题描述
我有一段JavaScript脚本,当SayHelloEvent事件触发时,两个独立的处理器会在控制台打印消息:
function signalSayHello() { var event = new Event('SayHelloEvent'); document.dispatchEvent(event); } document.addEventListener('SayHelloEvent', function SayHelloHandler1() { console.log('hello from Handler 1'); }); document.addEventListener('SayHelloEvent', function SayHelloHandler2() { console.log('hello from Handler 2'); });
现在我要怎么改写这段代码,让它在Google Apps Script中生效?
更新说明
我的最终目标是找到一种简洁的方式,让应用函数在应用调用的库函数指定的时机执行。目前我有一个替代方案,但需要把函数作为参数传递,如果要在库的多个函数间多次传递这类函数,代码会变得很混乱。下面是简化示例:
MyLibrary(库脚本)
function signalSayHello(sayHelloHandler) { if (typeof sayHelloHandler === 'function' ){ sayHelloHandler(); } }
MyApp1(应用脚本)
function sayHello() { MyLibrary.signalSayHello(function SayHelloHandler1() { console.log('hello from MyApp1'); }); }
MyApp2(应用脚本)
function sayHello() { MyLibrary.signalSayHello(function SayHelloHandler2() { console.log('hello from MyApp2'); }); }
我希望用事件替代函数传参的方式改写这段代码。
解决方案
Google Apps Script 没有浏览器环境中的document事件系统,需要自己实现一个简易的事件发射器来模拟事件订阅与触发逻辑,具体改造如下:
1. 修改MyLibrary库脚本
在库中实现事件管理核心逻辑,包含订阅、触发事件的方法:
// 存储事件与对应处理器的映射表 const eventHandlers = {}; /** * 订阅指定事件 * @param {string} eventName - 事件名称 * @param {Function} handler - 事件触发时执行的处理器函数 */ function on(eventName, handler) { if (!eventHandlers[eventName]) { eventHandlers[eventName] = []; } eventHandlers[eventName].push(handler); } /** * 触发指定事件 * @param {string} eventName - 事件名称 * @param {any} data - 传递给处理器的参数(可选) */ function emit(eventName, data) { const handlers = eventHandlers[eventName]; if (handlers && handlers.length > 0) { handlers.forEach(handler => { try { handler(data); } catch (e) { console.error(`事件处理器执行出错: ${e.message}`); } }); } } // 原signalSayHello函数改为触发SayHelloEvent事件 function signalSayHello() { emit('SayHelloEvent'); }
2. 修改MyApp1应用脚本
在应用中订阅SayHelloEvent事件,调用库函数触发事件:
// 初始化事件订阅(建议在脚本启动时执行,比如绑定到onOpen函数或单独执行) function initApp1() { MyLibrary.on('SayHelloEvent', function SayHelloHandler1() { console.log('hello from MyApp1'); }); } function sayHello() { MyLibrary.signalSayHello(); }
3. 修改MyApp2应用脚本
同理,MyApp2的实现如下:
function initApp2() { MyLibrary.on('SayHelloEvent', function SayHelloHandler2() { console.log('hello from MyApp2'); }); } function sayHello() { MyLibrary.signalSayHello(); }
使用说明
- 首次使用前需执行对应初始化函数(
initApp1或initApp2)完成事件订阅; - 调用
sayHello时,库会触发SayHelloEvent,对应的处理器自动执行; - 如果需要传递额外数据,可修改
emit方法的参数,在触发时传入,处理器中接收即可。
内容的提问来源于stack exchange,提问作者Daniel Vaca
相关产品推荐
相关产品推荐

