Design for fixing Promise serialization issue in build_eval_js.
Async functions return Promise which gets JSON.stringify'd to "{}".
🤖 Generated with [Qoder][https://qoder.com]
1.9 KiB
1.9 KiB
异步 Browser Script 支持设计
问题
collect_lineloss.js 的 buildBrowserEntrypointResult 是 async 函数,但 build_eval_js 生成的执行代码是同步的,导致 Promise 被 JSON.stringify 序列化为 {}。
日志表现:
[execute_browser_script_impl] 返回成功, payload 长度: 4
返回 {}(4字符) 而不是实际的报表数据。
根本原因
callback_backend.rs 的 build_eval_js 函数:
var v=(function(){return {script}})(); // 同步执行
var t=(typeof v==='string')?v:JSON.stringify(v); // Promise -> "{}"
当 script 返回 Promise 时,JSON.stringify(Promise) 返回 {}。
解决方案
修改 build_eval_js 支持 Promise:
- 用
await等待 script 执行结果 - 检测结果是否为 Promise,如果是则等待 resolve
- 保持对同步脚本的向后兼容
实现细节
修改 src/browser/callback_backend.rs 的 build_eval_js 函数:
(async function(){
try {
var v = await (function(){return {script}})();
// 等待 Promise resolve
if (v && typeof v.then === 'function') {
v = await v;
}
var t = (typeof v === 'string') ? v : JSON.stringify(v);
// ... 回调逻辑保持不变
} catch(e) {}
})()
关键点:
- 包装整个 IIFE 为 async
- 用
await等待 script 执行 - 检测 Promise-like 对象 (
v.then === 'function') - 向后兼容:同步脚本直接返回值,async 脚本返回 Promise 后被 await
影响范围
src/browser/callback_backend.rs: 修改build_eval_js函数- 所有
browser_script类型的 skill 自动支持 async
测试验证
- 运行
cargo test确保现有测试通过 - 端到端测试
tq-lineloss-report.collect_lineloss返回实际数据而非{} - 验证同步脚本(如知乎热榜)仍然正常工作
不在范围内
- 不修改
wrap_browser_script(方案 C 的做法) - 不修改 skill 脚本本身