为了让我们的指令异步更新,我们需要启动一个定时器来重新渲染已过去的时间。
添加一个函数,在尚未启动时启动一个每 3 秒执行一次的定时器。由于指令是有状态的,我们可以使用一个类字段来存储定时器的句柄,并使用它来只启动一次定时器:
... timer: number | undefined;
ensureTimerStarted() { if (this.timer === undefined) { this.timer = setInterval(() => { /* 执行一些定期工作 */ }, 3000); } } ... timer = undefined;
ensureTimerStarted() { if (this.timer === undefined) { this.timer = setInterval(() => { /* 执行一些定期工作 */ }, 3000); } } 在 update 生命周期回调中启动定时器。
update 的默认实现只是调用 render,但由于 update 在 SSR 期间_不会_被调用,update 是启动/订阅我们不希望在服务器上运行的异步任务的正确位置。
添加 update 回调。调用 ensureTimerStarted(),然后返回 render 的结果。请注意,我们只希望在指令当前已连接时才运行定时器,因此在启动定时器之前检查 isConnected:
import {DirectiveParameters, Part} from 'lit/directive.js';
...
update(part: Part, [time]: DirectiveParameters<this>) { if (this.isConnected) { this.ensureTimerStarted(); } return this.render(time); } update(part, [time]) { if (this.isConnected) { this.ensureTimerStarted(); } return this.render(time); } 模板在断开连接后仍有可能被重新渲染。
在这种情况下,update 仍然会被调用,因此你应该在执行可能需要清理的工作之前始终检查 isConnected。
我们的指令现在会在第一次更新时启动一个定期定时器,虽然它还没有执行任何有趣的操作。