hamibot 双线程运行下 还有多个setinervel 再跑 如何优化运行内存

已存档
我日你妈PPMT · 21 天前
第 1 条补充
·
21 天前

事件通信方式协作运行 如何做

回答

Hamibot AI
1
· 21 天前

Hamibot 目前并不支持真正的双线程并行执行,其运行环境基于 Rhino 引擎,JavaScript 代码在单一线程中执行。你提到的“双线程”可能是指使用了 setInterval 或多个定时任务模拟并发行为。

在使用多个 setInterval 的情况下,随着定时器增多和脚本逻辑复杂化,内存占用会上升,主要原因是:

  • 定时器持续持有变量引用,导致无法被回收。
  • 多个定时任务频繁执行,造成事件堆积。
  • 脚本未及时清理无用对象或未释放资源。

优化建议如下:

1. 减少不必要的 setInterval

每个 setInterval 都会创建一个后台任务,增加运行负担。优先考虑是否可以用 setTimeout 递归调用替代,便于控制生命周期。

// 文档地址 https://docs.hamibot.com/

var timer = setInterval(function () {
    // 执行任务
    if (/* 满足结束条件 */) {
        clearInterval(timer); // 及时清除
    }
}, 5000);

务必在不需要时调用 clearInterval 清理定时器,避免内存泄漏。


2. 合并同类任务

将多个小任务合并为一个定时器处理,减少定时器数量。

// 文档地址 https://docs.hamibot.com/

setInterval(function () {
    taskA();
    taskB();
    taskC();
}, 3000);

比分别用三个 setInterval 更节省资源。


3. 避免闭包中的大对象引用

不要在 setInterval 回调中长期持有大量数据或 UI 对象,防止 GC 无法回收。

// ❌ 错误示例:持续引用大数据
var bigData = largeArray(); 
setInterval(function () {
    console.log(bigData[0]); // bigData 一直存在
}, 2000);

应尽量缩小作用域,或只保留必要引用。


4. 使用模块化与函数封装

将逻辑拆分为独立函数,执行完后局部变量可被及时释放。

// 文档地址 https://docs.hamibot.com/

function runTask() {
    var temp = "临时变量";
    // 任务完成后,temp 会在函数退出后被回收
}
setInterval(runTask, 5000);

5. 主动释放资源

  • 不再使用的变量设为 null
  • 解除事件监听(如使用无障碍服务时注意)。
  • 脚本结束前调用 hamibot.exit() 并清理所有定时器。
// 文档地址 https://docs.hamibot.com/

var id1 = setInterval(task1, 2000);
var id2 = setInterval(task2, 3000);

// 结束时
clearInterval(id1);
clearInterval(id2);
hamibot.exit();

6. 控制脚本频率

避免过于频繁地执行操作(如每 100ms 执行一次),推荐最小间隔不低于 500ms,除非必要。


7. 分离长时间运行脚本

如果功能复杂,建议将不同任务拆分为多个脚本,通过 launchApp 或事件通信方式协作运行,降低单个脚本内存压力。


总结

优化核心是:

  • 减少定时器数量
  • 及时清理资源
  • 避免长时变量引用
  • 合理设计执行频率

这样可以显著降低 Hamibot 运行时的内存占用,提升稳定性。


补充回答 1

在 Hamibot 中,可以通过 events.broadcast 实现多个脚本之间的事件通信与协作运行。events.broadcast 是一个全局共享的 EventEmitter,所有正在运行的脚本都可以监听或发送广播事件,从而实现跨脚本通信。


✅ 使用步骤

1. 发送广播事件

在一个脚本中使用 events.broadcast.emit(eventName, ...args) 发送事件。

// 文档地址 https://docs.hamibot.com/

// 发送一个名为 'task_done' 的事件,并携带数据
events.broadcast.emit('task_done', 'login_completed', true);

2. 监听广播事件

在另一个脚本中使用 events.broadcast.on(eventName, callback) 来监听该事件。

// 文档地址 https://docs.hamibot.com/

// 监听 task_done 事件
events.broadcast.on('task_done', function (taskName, success) {
    toast('收到任务完成通知: ' + taskName + ', 成功: ' + success);
    
    if (taskName === 'login_completed' && success) {
        // 触发后续操作
        startMainTask();
    }
});

// 保持脚本运行(避免立即退出)
setInterval(() => {}, 1000);

🧩 实际协作示例:登录脚本 + 主任务脚本

假设你有两个脚本:

  • 脚本A:负责模拟登录操作。
  • 脚本B:等待登录完成后执行主任务。
脚本A:登录完成后发送通知
// 文档地址 https://docs.hamibot.com/

auto.waitFor();

// 模拟登录流程...
toast("开始登录...");
sleep(5000); // 模拟耗时操作

// 登录成功后广播通知
events.broadcast.emit('login_success', {
    account: 'user123',
    time: new Date().toLocaleString()
});

hamibot.exit(); // 退出当前脚本
脚本B:监听登录成功并继续执行
// 文档地址 https://docs.hamibot.com/

auto.waitFor();

// 监听登录成功的广播
events.broadcast.on('login_success', function (data) {
    toast("登录成功,账号:" + data.account + ",时间:" + data.time);
    startMainWork(); // 执行主任务
});

function startMainWork() {
    // 主业务逻辑
    toast("启动主任务...");
    // ...
}

// 保持脚本存活以接收事件
setInterval(() => {}, 1000);

只要两个脚本都处于运行状态,就能通过广播进行通信。


⚠️ 注意事项

  1. 脚本必须正在运行才能接收到事件
    如果目标脚本未启动或已结束,则无法收到广播。

  2. 事件是异步的
    广播发出后不会阻塞,也不会确认对方是否处理。

  3. 避免重复监听
    多次调用 on 会注册多个监听器,建议在合适时机使用 off() 解除:

    var listener = function () { ... };
    events.broadcast.on('event', listener);
    // 之后移除
    events.broadcast.off('event', listener);
    
  4. 不要传递函数或复杂对象
    参数应为可序列化的数据类型(如字符串、数字、普通对象),避免传入函数、锁、线程等。


✅ 最佳实践建议

  • 将公共事件名称统一定义为常量,避免拼写错误。
  • 脚本启动时先注册监听,再执行其他逻辑。
  • 关键任务完成后及时发送状态通知,提高协作效率。

通过 events.broadcast,你可以轻松实现多脚本协同工作,替代“多线程”场景下的通信需求,同时降低内存压力和逻辑耦合度。

ℹ️ 本回答由 AI 生成,内容仅供参考