42 lines
2.8 KiB
Plaintext
42 lines
2.8 KiB
Plaintext
// 把 callback-free 文件 Task 与 ui.spawn 协作函数组合:await 保存执行位置,等待完成后继续,不阻塞 VM worker。
|
|
// readText 的 file 与 spawn 的 workflow 使用不同 key,分别管理读取和等待流程。
|
|
// 保存 provider Task、协程 Task 和结果;两种任务都是托管对象,可以从 Console 独立查看。
|
|
class AwaitReader {
|
|
output: TextBlock
|
|
status: TextBlock
|
|
// workflow 句柄由 ui.spawn 返回,用于观察协作函数状态和最终返回值。
|
|
task: Object
|
|
// provider 句柄由 ui.readText 返回,apply 的 await 等待它;两个字段不是同一个 Task 的别名。
|
|
file: Object
|
|
response: String
|
|
// await 在文件未完成时挂起并保留 self/操作数;恢复后只执行后半段一次,再把字符串作为 workflow.result。
|
|
function apply(self: AwaitReader): String {
|
|
// 调度器启动 apply 后遇到未完成 file 会保留续体,后续 provider 就绪再恢复;成功结果才赋给 response。
|
|
self.response = await self.file
|
|
self.output.text = "读取完成;在 REPL 查看 reader.response 或 reader.task.result()"
|
|
// 正常返回值成为 workflow.result(),与 file 的读取结果来源相同但属于另一个任务结果。
|
|
return self.response
|
|
}
|
|
// 先创建读任务,再调度普通函数 apply;spawn 而非新 async 语法提供可暂停执行上下文。
|
|
function read(self: AwaitReader, path: String): Unit {
|
|
// 先安装本轮文件任务,省略成功回调;它以可 await 的结果状态通知 workflow。
|
|
self.file = ui.readText(self, "file", path)
|
|
// 再安装 workflow,捕获的是绑定 self 的方法;spawn 安排稍后执行,不在这一赋值处同步跑完 apply。
|
|
self.task = ui.spawn(self, "workflow", self.apply)
|
|
// 启动后清上次业务结果及显示提示,新的 await 恢复后才写入本轮文本。
|
|
self.response = ""
|
|
self.output.text = "等待文件"
|
|
// 显示的是 workflow 状态,等待 provider 时它仍报告 running;结束后 result 可从 Task 或 response 读取。
|
|
self.status.bind("text", self.task.status)
|
|
}
|
|
}
|
|
output = TextBlock("在 REPL 调用 reader.read(绝对路径字符串)")
|
|
// 只展示协作 workflow 的状态,provider 自身状态可从 reader.file 单独查询。
|
|
status = TextBlock("")
|
|
// 占位值只用于满足初始字段构造;在 read 内被真实 Task 替换,页面建立不自动读文件。
|
|
reader = AwaitReader(output,status,ui.state(0),ui.state(0),"")
|
|
// 页面只投影 status/output,两个任务 owner 都是 reader,页面可见与否不是该普通 owner 的交付资格条件。
|
|
page = Page()
|
|
page.title = "await 文件"
|
|
page.render(Column(24,16,status,output))
|