Angular4 - 我是否需要取消订阅setTimeout调用?

时间:2017-10-24 13:45:20

标签: javascript angular rxjs settimeout

在一些地方,我需要调用setTimeout,例如:

setTimeout(() => this.isSaving[index] = false, 500);

当我的组件被销毁时,该超时会继续发出吗?换句话说,我需要捕获返回的observable,如下所示:

this.subTimeout = setTimeout(() => this.isSaving[index] = false, 500);

然后在我的破坏钩子中取消订阅:

ngOnDestroy() {
  this.subTimeout.unsubscribe();
}

如果我必须在我的组件中启动几个setTimeout,这会很费力。有没有更简单的方法来摧毁它们?就像使用takeUntil(destroy $)?

2 个答案:

答案 0 :(得分:7)

  

我是否需要取消订阅setTimeout调用?...当我的组件被销毁时,该超时是否会继续发出?

您无需担心重复执行回调。 setTimeout只执行一次然后它已经死了。通常很好的做法是考虑时间将耗尽的可能性,并且回调仅在组件被销毁之后才执行。在我自己的应用程序中,我将所有需要撤消的订阅放入数组中,并且我在ngOnDestroy中有一个标准的批量取消订阅作业。您的超时也可以这样做:

// component property
timeOutIDs:number[] = [];
...
// triggering a timeout and capturing the id
this.timeOutIDs.push(
    setTimeout(() => this.isSaving[index] = false, 500)
);
...
// inside ngOnDestroy
this.timeoutIDs.forEach(id => clearTimeout(id));

使用这种方法,您不需要多个变量来存储不同的超时ID,并且如果始终push setTimeout的返回值,您可以确保正确清除所有超时你的ids数组。

附加说明:您应该始终取消setInterval来电并始终取消订阅开放式订阅。

答案 1 :(得分:2)

这取决于setTimeout内部回调的内容,但通常应该取消订阅。他们无法以神奇的方式取消订阅。他们的回调将以任何方式被解雇,并可能导致错误或不良副作用。

最好在某处分配超时,至少是为了测试目的。应该在ngOnDestroythis.subTimeout.unsubscribe()中完成的事情假定通过RxJS执行超时:

this.subTimeout = Observable.timer(500).subscribe(() => { 
  this.isSaving[index] = false;
});

可以改进的方式取决于这些超时的用途。