task
task
功能
创建轻量后台任务。task(fn, ...args) 会立即返回 Task 对象,任务函数在后台独立 VM 中执行;主流程可通过 await() 阻塞等待结果,通过 done() 查询完成状态,通过 result() 非阻塞读取结果,也可以通过 on_done(fn) 在长期 VM 事件循环中注册完成回调。
后台任务采用快照传值,不共享主 VM 的数组、对象、闭包或全局变量引用。显式参数、闭包捕获和可能访问的全局变量都会在创建任务时快照。
语法
t = task(fn(value) { return value + 1 }, 6) value = t.await() done = t.done() result = t.result()
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| fn | Fn | 是 | 无 | 后台任务入口函数,只执行一次。 |
| ...args | 任意可快照值 | 否 | 无 | 传给任务入口函数的显式参数,按创建任务时快照。 |
返回值
| 类型 | 说明 |
|---|---|
| Task | 后台任务对象,包含 await、done、result、on_done 方法。 |
Task 方法
| 方法 | 返回值 | 说明 |
|---|---|---|
| await() | 任意值 | 阻塞等待任务完成;成功返回结果;任务内部 throw 时重新抛出;普通运行时错误按运行时错误返回。 |
| done() | Bool | 非阻塞判断任务是否完成。 |
| result() | 任意值 / Empty | 非阻塞读取结果;未完成返回 empty;成功返回结果;任务内部 throw 时重新抛出。 |
| on_done(fn) | Task | 注册完成回调并返回当前 Task,方便链式调用。 |
on_done 回调
t.on_done(fn(result, err, status) { if status != 'success' { return empty } // 输出:123 print result })
| 参数 | 类型 | 说明 |
|---|---|---|
| result | 任意值 / Empty | 任务成功时为返回值;失败或 throw 时为 empty。 |
| err | 任意值 / String / Empty | 任务 throw 时为抛出的值;普通失败时为错误文本;成功时为 empty。 |
| status | String | success、throw 或 failed。 |
on_done() 回调在注册它的 VM 线程执行,不会在后台任务线程直接执行。CLI 脚本和桌面长期 VM 会在主流程结束后的事件边界分发回调;Web 请求 VM 生命周期短,不能注册 on_done()。
可快照类型
| 类型 | 说明 |
|---|---|
| Null | 保留显式空值。 |
| Empty | 保留缺失值;序列化到 JSON 时仍按 JSON null 输出。 |
| Int / Float / Bool / String | 按值复制。 |
| Array / Object | 递归深快照,后台 VM 和主 VM 不共享可变引用。 |
函数值、类实例、正则对象、日期对象、文件句柄、数据库连接、网络连接、设备句柄、进程句柄和原生对象不能进入任务快照,也不能作为任务结果返回。
示例
t = task(fn(value) { sleep(100) return value + 1 }, 122) value = t.await() // 输出:123 print value
t = task(fn() { sleep(100) return 7 }) pending = t.result() sleep(200) value = t.result() // 输出:empty print pending // 输出:7 print value
data = {count: 1} t = task(fn(item) { item.count = 9 return item.count }, data) data.count = 2 result = t.await() // 输出:2 print data.count // 输出:9 print result
task(fn() { return 123 }).on_done(fn(result, err, status) { if status == 'success' { // 输出:123 print result } })
注意事项
-
task(fn, ...args)只创建轻量后台任务,不引入 async fn、await 关键字、Promise、channel 或共享可变状态。 - 任务函数在独立 VM 中执行,显式参数、捕获变量和全局变量按创建任务时快照。
-
await()、task_all()和task_race()会阻塞当前执行流;Web 请求上下文中会直接拒绝这些同步等待方法。 -
Task.on_done()只能用于 CLI 常驻脚本和桌面长期 VM,不能用于 Web 请求上下文。 - Web 请求中允许提交
task(fn, ...args),但不能在请求内注册回调或等待完成;完整规则见:Web 阻塞 API 策略。 - 后台任务队列、线程数、快照大小、完成订阅和回调表都有上限;超过上限会返回运行时错误。
- 可通过环境变量
BT_TASK_WORKERS和BT_TASK_QUEUE调整后台任务线程数和队列长度,实际值仍会被运行时安全上限约束。