docs: add async browser script support design
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]
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
# 异步 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` 函数:
|
||||||
|
```javascript
|
||||||
|
var v=(function(){return {script}})(); // 同步执行
|
||||||
|
var t=(typeof v==='string')?v:JSON.stringify(v); // Promise -> "{}"
|
||||||
|
```
|
||||||
|
|
||||||
|
当 script 返回 Promise 时,`JSON.stringify(Promise)` 返回 `{}`。
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
修改 `build_eval_js` 支持 Promise:
|
||||||
|
|
||||||
|
1. 用 `await` 等待 script 执行结果
|
||||||
|
2. 检测结果是否为 Promise,如果是则等待 resolve
|
||||||
|
3. 保持对同步脚本的向后兼容
|
||||||
|
|
||||||
|
## 实现细节
|
||||||
|
|
||||||
|
修改 `src/browser/callback_backend.rs` 的 `build_eval_js` 函数:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
(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
|
||||||
|
|
||||||
|
## 测试验证
|
||||||
|
|
||||||
|
1. 运行 `cargo test` 确保现有测试通过
|
||||||
|
2. 端到端测试 `tq-lineloss-report.collect_lineloss` 返回实际数据而非 `{}`
|
||||||
|
3. 验证同步脚本(如知乎热榜)仍然正常工作
|
||||||
|
|
||||||
|
## 不在范围内
|
||||||
|
|
||||||
|
- 不修改 `wrap_browser_script`(方案 C 的做法)
|
||||||
|
- 不修改 skill 脚本本身
|
||||||
Reference in New Issue
Block a user