为了让我们的指令异步更新,我们需要启动一个定时器来重新渲染已过去的时间。

添加一个函数,在尚未启动时启动一个每 3 秒执行一次的定时器。由于指令是有状态的,我们可以使用一个类字段来存储定时器的句柄,并使用它来只启动一次定时器:

time-ago.

Permalink to "time-ago."
...
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

我们的指令现在会在第一次更新时启动一个定期定时器,虽然它还没有执行任何有趣的操作。