您好,我这边 Hamibot 脚本遇到两个引擎相关异常,麻烦帮忙看下:
问题 1:子线程内箭头函数 map 自定义变量报 “变量未定义”
场景:用threads.start()开启独立后台线程,线程里执行代码:
oldText.split("\n").map(lineItem=>lineItem.trim()).filter(lineItem)
报错:ReferenceError: "lineItem" 未定义
不管我把变量改成 r、item、lineItem,只要是 map 箭头函数自定义参数,子线程都会报这个错;
奇怪点:完全相同代码放在主线程运行一点报错都没有,仅后台子线程触发报错;
影响:后台上传轮询线程直接崩溃中断,文件生成、数据推送功能失效,但页面操作主线程能正常跑完任务。
问题 2:正则 /gi 忽略大小写修饰符匹配失效
正则:/(wx|wechat|微信|加v|v|微)[-::\s]?([a-zA-Z0-9]{6,20})/gi
现象:只能匹配小写v,文本里大写V: qj888完全捕获不到,微信号提取为空;标准 JS 环境里带 gi 是能正常识别大写 V 的,只有 Hamibot 内置引擎失效。
想咨询两点:
Hamibot threads.start() 子线程里,是不是对 map 箭头函数的局部变量存在兼容 bug?有没有替代的兼容写法?
内置 JS 正则引擎对 /gi 全局忽略大小写修饰符支持是否完整?大写关键词匹配失效该怎么处理?

HAMI_6893877807 · 2 小时前

回答

Hamibot AI
1
· 2 小时前

你的两个问题都源于 Hamibot 使用的 JavaScript 引擎(Rhino 1.7.15)对较新语法及正则特性的兼容性限制。下面直接给出原因和兼容写法。


问题 1:子线程内箭头函数 mapReferenceError: lineItem 未定义

原因:Rhino 1.7.15 对箭头函数(=>)的支持不完整,尤其在 threads.start() 派生的子线程环境中,箭头函数的词法作用域绑定可能出现异常,导致参数被视为未定义。主线程没有问题是因为作用域环境差异,但这依然是引擎兼容性风险。

解决方案:将所有箭头函数替换为普通 function 表达式,这是 Rhino 完全支持的写法。

原代码:

oldText.split("\n").map(lineItem=>lineItem.trim()).filter(lineItem)

改为:

// 文档地址 https://docs.hamibot.com/
oldText.split("\n").map(function(lineItem) {
    return lineItem.trim();
}).filter(function(lineItem) {
    // 此处 filter 的逻辑需要补全,示例假设过滤非空行
    return lineItem && lineItem.length > 0;
});

如果是仅过滤空字符串,可以简化为:

oldText.split("\n").map(function(lineItem) {
    return lineItem.trim();
}).filter(function(lineItem) {
    return lineItem !== "";
});

杜绝在脚本中使用箭头函数,同时避免函数默认参数等 ES6 特性,能确保在多线程环境稳定运行。


问题 2:正则 /gi 忽略大小写修饰符匹配失效

原因:这不是 /gi 修饰符本身失效,而是 Rhino 1.7.15 的正则引擎在处理某些 Unicode 字符(如中文“微”以及大小写转换)时,对 i 标志的支持存在偏差。尤其是文本中的大写 V 无法与小写 v 匹配,可能是因为引擎未将 V 正确视为 v 的忽略大小写等价形式,或者该正则中的 v 被其他分支(如中文“微”)干扰。标准 JS 环境通常能正确处理,但 Rhino 存在这样的边缘情况。

解决方案:采用“手动忽略大小写”的兼容策略,即不依赖 /i 标志,而是将待匹配文本和目标字母都转为同一种大小写,再使用不带 i 的正则。

示例

// 文档地址 https://docs.hamibot.com/
var regex = /(wx|wechat|微信|加v|v|微)[-_::\s]?([a-zA-Z0-9_]{6,20})/g; // 去掉 i 标志
var text = "加V: qj888 客服微信:WX123456";
var lowerText = text.toLowerCase(); // 统一转小写
var match;
while ((match = regex.exec(lowerText)) !== null) {
    // 如果需要保留原始大小写,可以记录位置后从原字符串截取
    var originalMatch = text.substring(match.index, match.index + match[0].length);
    console.log("匹配到:" + originalMatch);
}

如果必须保留原始大写信息,可以先用正则匹配位置,然后从原始文本截取。但更稳健的做法是:放宽正则中的 v[vV],并保留 /g

var regex = /(wx|wechat|微信|加[vV]|[vV]|微)[-_::\s]?([a-zA-Z0-9_]{6,20})/g;

这样既避免了 /i 的不可靠,又能直接匹配大小写。


总结:你的两个问题都属 Rhino 引擎兼容性限制,通过替换箭头函数为普通函数、避免依赖 /i 标志(改用手动大小写处理或扩展字符集)即可稳定运行。今后编写脚本时,请务必遵循“不使用箭头函数、不定义函数默认参数”等兼容性要求,并参考官方文档 docs.hamibot.com 获取最新兼容性说明。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实