docs: clarify task example ownership and failure boundaries
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// 异步 UTF-8 文件读取:在 Console 调用 reader.read(绝对路径),后台 provider 只交付文本,VM worker 执行业务回调。
|
||||
// owner/key 相同的新读取替换旧任务;失败只记录 Task.error,不执行 apply。
|
||||
// owner/key 相同的新读取替换旧任务;provider 读取失败记录 Task.error、不执行 apply;apply 自身失败则遵循共享运行时停域规则。
|
||||
// 持有三个显示对象与当前任务;task 初值占位,第一次 read 后替换为真实 Task。
|
||||
class FileReader {
|
||||
// 这三个字段保存已构造的文字对象引用,回调更新同一业务对象,不创建一份新的页面或复制 Mount。
|
||||
@@ -11,6 +11,7 @@ class FileReader {
|
||||
// 仅成功时调用,result 在成功回调期间已可读;写原 TextBlock 触发显示刷新。
|
||||
function apply(self: FileReader): Unit {
|
||||
// 任务调度器在 I/O 成功且仍有交付资格时调用绑定的 apply;self 是原 reader,调用者无需另外传参。
|
||||
// 本例适用于不超过 TextBlock 16 KiB UTF-8 字节预算的文件;readText 自身允许至多 1 MiB,读取成功不保证这次控件赋值合法。
|
||||
self.output.text = self.task.result()
|
||||
}
|
||||
// 以 self 为 owner、file 为 key 启动读取,清空旧输出,并把状态/错误文字绑定到当前任务。
|
||||
|
||||
@@ -19,6 +19,7 @@ class TextFetcher {
|
||||
function fetch(self: TextFetcher, url: String): Unit {
|
||||
// url 来自显式 fetch 调用,HTTP(S) GET 由后台 provider 完成;新句柄返回不代表网络已完成。
|
||||
self.task = ui.fetchText(self, "request", url, self.apply)
|
||||
// 只有 fetchText 成功创建新句柄才清旧结果;若 URL 校验/任务额度拒绝,上面的调用报错,下面不会执行。
|
||||
// 同步清旧结果,避免新请求等待期间让 Console 把旧响应误认成新请求结果。
|
||||
self.response = ""
|
||||
self.output.text = ""
|
||||
|
||||
@@ -12,6 +12,7 @@ class AwaitReader {
|
||||
// await 在文件未完成时挂起并保留 self/操作数;恢复后只执行后半段一次,再把字符串作为 workflow.result。
|
||||
function apply(self: AwaitReader): String {
|
||||
// 调度器启动 apply 后遇到未完成 file 会保留续体,后续 provider 就绪再恢复;成功结果才赋给 response。
|
||||
// 依赖取消会取消等待流程;依赖失败在 await 处变成源错误,本例没有捕获逻辑,也不会执行后面的完成提示。
|
||||
self.response = await self.file
|
||||
self.output.text = "读取完成;在 REPL 查看 reader.response 或 reader.task.result()"
|
||||
// 正常返回值成为 workflow.result(),与 file 的读取结果来源相同但属于另一个任务结果。
|
||||
@@ -21,7 +22,8 @@ class AwaitReader {
|
||||
function read(self: AwaitReader, path: String): Unit {
|
||||
// 先安装本轮文件任务,省略成功回调;它以可 await 的结果状态通知 workflow。
|
||||
self.file = ui.readText(self, "file", path)
|
||||
// 再安装 workflow,捕获的是绑定 self 的方法;spawn 安排稍后执行,不在这一赋值处同步跑完 apply。
|
||||
// 再安装 workflow,捕获的是绑定 self 的源方法;它在后续调度量子内推进,不在此处同步跑完 apply。
|
||||
// file/workflow 分属两个 key;连续启动不是一笔原子事务,若 spawn 创建失败,前面已创建的文件任务不会自动撤回。
|
||||
self.task = ui.spawn(self, "workflow", self.apply)
|
||||
// 启动后清上次业务结果及显示提示,新的 await 恢复后才写入本轮文本。
|
||||
self.response = ""
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// 协作任务示例:两个 ui.spawn 各自保留执行帧,worker 按指令量子轮转推进。
|
||||
// 这里刻意重复增量语句,方便看到暂停点;取消不回滚已经发生的 steps 写入,单个原生调用仍是原子边界。
|
||||
// 这里刻意重复增量语句,方便观察推进;量子按 VM 指令计数,不保证每个 increment 或每组 16 条之后恰好暂停。
|
||||
// 取消不回滚已经发生的 steps 写入,单个原生调用仍是原子边界。
|
||||
// 每个实例有独立 steps 状态,两个任务不会把局部帧或计数存储混在一起。
|
||||
class CooperativeWork {
|
||||
// 保存 ui.state 返回的原生可变计数,每个 CooperativeWork 构造传入不同对象。
|
||||
|
||||
@@ -33,6 +33,7 @@ class CycleRect: RectBlock {
|
||||
}
|
||||
}
|
||||
// 创建临时 Page 和 CycleRect,相互引用后挂载,再把 Page/Task 分别放入两个外部 holder。
|
||||
// 按 mountCycle → 观察 → releaseCycle 的顺序使用;未释放前重复 mountCycle 会另建页面并覆盖 holder,不是重置原环。
|
||||
function mountCycle(): Unit {
|
||||
// 供 Console 手工调用的零参入口,加载此文件只定义函数,不立即创建临时环或开始五分钟等待。
|
||||
transient = Page()
|
||||
|
||||
@@ -12,7 +12,8 @@ class Actions {
|
||||
// 每次启动 1500ms 的 load 定时器;相同 owner/key 只有最新任务继续等待。
|
||||
// 三个按钮的 click 事件路由调用 schedule,event 为事件参数;方法内部不读取它,只创建延时任务。
|
||||
function schedule(self: Actions, event: Event): Unit {
|
||||
// 返回句柄未存入字段也不立即取消,调度器继续维护任务;同一 owner/load 新任务替换旧等待。
|
||||
// 返回句柄未存入字段也不立即取消:owner 的任务字典强持有 Task,调度器本身仅保存弱索引。
|
||||
// 此处 owner 仍由全局/业务字段保留;同一 owner/load 新任务替换旧等待,不靠局部 Task 变量维持资格。
|
||||
ui.after(self.owner, "load", 1500, self.complete)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user