定时器回调应该更新指令渲染的值——但请注意,定时器回调在正常的指令 update/render 生命周期_之外_触发,而我们通常是在该生命周期中返回值供指令渲染。

我们可以使用 AsyncDirectivesetValue API 在指令的正常更新周期之外,更新渲染到模板中的指令结果。

在我们的场景中,需要在定时器回调中引用 time 参数。为了让用户的 time 参数在 update 之外可用,将其存储在另一个类字段中:

time!: Date;

update(part: Part, [time]: DirectiveParameters<this>) {
this.time = time;
...
}
update(part, [time]) {
this.time = time;
...
}

然后在我们的定时器回调中,我们可以调用 setValue,使用我们的 render 结果,这将使用当前已过去的时间重新格式化日期。

this.setValue(this.render(this.time));

恭喜!如果你等几秒钟,你现在应该能看到使用指令渲染的时间会定期更新,使用 timeago 库的规则逐步从"刚刚"变为"几秒前"再到"几分钟前"等。

此实现包含内存泄漏。

虽然指令可以工作,但存在潜在的内存泄漏——如果元素从 DOM 中断开连接,定时器会继续触发,并持有对指令和底层 DOM 的引用。

接下来,我们将添加生命周期管理,在指令不再需要时进行清理。