You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:47:16