构建

不去问 — 轮询比「浪费」更糟的地方

作者: makemind · 2026年4月24日

到第四篇为止,想知道最新的值就得去问——每秒问一次,或者靠人刷新。

订阅

client.onResourceUpdated((uri) {
  // The notification says only that it changed. Read to learn what to.
  seen.add(uri);
  stdout.writeln('notified: $uri');
});

await client.subscribeResource('desk://waiting');

然后让值真的变一下。

await client.callTool('desk.admit', {'count': 1});
subscribed to desk://waiting
notified: desk://waiting
after the notification, reading gives {waiting: 2}
notifications received: 1

通知只带 uri

处理器收到的是一个 uri。变成几个人不会来。服务端第六篇讲了为什么不带值;在接收这一侧,它的意思就是 你必须去读。

final now = await client.readResource('desk://waiting');

多走一趟看着吃亏,可这样永远是对的。不管来几条通知、什么顺序,读的那一刻的值 就是最新的。

轮询真正的问题

拒绝轮询的理由通常是成本。每秒敲一次服务端是浪费。

那是次要的。真正的问题是,你看不到两次询问之间。

09:00:00    轮询 → waiting 3
09:00:00.4  进来两个 → waiting 1
09:00:00.7  来了一个 → waiting 2
09:00:01    轮询 → waiting 2

画面从 3 到了 2。它没看到曾经是 1 的那一刻。 如果只要最终值,无所谓;可要是有「归零就报警」这类规则,那条规则永远不会触发。

把间隔调小也消不掉,只是变窄。而越窄,浪费越大。

结束就退订

await client.unsubscribeResource('desk://waiting');

画面关掉就退订。不退,服务端会一直往一个不存在的对象发。

真板那篇里的 ESP32 把这件事放进了 画面定义里 —— onReady 订阅,onDestroy 解除。生命周期写在画面上,客户端就忘不掉。

此内容需要开发者或更高等级

登录并升级您的方案即可继续阅读。

查看方案
Twitter