Skip to Content
内部原理生命周期与 Runtime 循环

生命周期与 Runtime 循环

很多人第一次接触 Ansiq,会把下面两件事混成一件事:

  • app 生命周期
  • runtime 的每次更新循环

它们有关,但不是同一个层次。

先看 app 生命周期

一个 Ansiq app 在高层上通常会经历:

  1. 创建 app 实例
  2. 进入 terminal session
  3. 调用 mount(...)
  4. 做第一次 render(...)
  5. 进入 runtime loop
  6. 在输入、消息、响应式变化下反复 update(...) / rerender
  7. 退出并恢复终端状态
App 生命周期
1create app
2enter terminal session
3mount(...)
4first render(...)
5runtime loop
6exit and restore terminal

这条链回答的是:

一个 app 在一生中会经历哪些阶段?

再看 runtime loop

runtime loop 关注的是另一件事:

某一次变化发生后,系统如何把它稳定地落到终端上?

Ansiq 当前真正协调的是:

  • 输入事件
  • app 消息
  • reactive flush
  • rerender 决策
  • partial relayout
  • invalidated regions
  • framebuffer diff
  • terminal patch emission
一次更新进入终端的主链
1input / async messages / reactive flush
2dirty scope collection
3subtree rerender or full rerender
4partial relayout
5invalidated regions
6framebuffer diff
7terminal patch emission

App trait 的四个关键方法

pub trait App { type Message: Send + 'static; fn mount(&mut self, _handle: &RuntimeHandle<Self::Message>) {} fn render(&mut self, cx: &mut ViewCtx<'_, Self::Message>) -> Element<Self::Message>; fn update(&mut self, message: Self::Message, handle: &RuntimeHandle<Self::Message>); fn on_unhandled_key( &mut self, _key: Key, _handle: &RuntimeHandle<Self::Message>, ) -> bool { false } }

mount(...)

mount(...) 适合做“应用一启动就应该存在”的事情,例如:

  • 启动后台采样
  • 建立长连接
  • 发出初始消息

它不负责画 UI。

render(...)

render(...) 负责描述当前 UI 树,并建立这一轮的响应式读取。

它不直接发 terminal patch,也不自己决定 relayout。

update(...)

update(...) 负责消费消息并修改 app 状态。

它回答的是:

  • 用户做了什么
  • 后台任务带回了什么新事实
  • 这些事实怎样变成 app state

on_unhandled_key(...)

当 widget 没有消费某个按键、runtime 的全局焦点导航也没有消费时,按键会回到 app。

它适合:

  • 全局快捷键
  • Escape 取消
  • 模式切换
  • 命令入口
fn on_unhandled_key( &mut self, key: Key, handle: &RuntimeHandle<Self::Message>, ) -> bool { if key == Key::Esc { let _ = handle.emit(Message::Cancel); return true; } false }

一条常见误解

很多框架把主循环写成“有事件就重画一次”。Ansiq 不够用这么简单的模型,因为它要同时协调:

  • 输入
  • 异步任务
  • 局部 rerender
  • 局部 relayout
  • viewport / history

所以 runtime loop 在 Ansiq 里是架构边界,不是内部细节。

下一步

继续阅读 响应式响应式系统原理
前一页教你怎么用 signal / computed / effect,后一页解释它们为什么要和 UI tree 分层。

Last updated on