Angular4 - мне нужно отписаться от звонков setTimeout?

1

В нескольких местах мне нужно было вызвать setTimeout, например:

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

Когда мой компонент будет уничтожен, будет ли этот тайм-аут продолжать излучать? Другими словами, мне нужно захватить возвращаемое наблюдаемое, например:

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

а затем нечистый в моем крюке уничтожения:

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

Это становится трудоемким, если мне нужно инициировать несколько setTimeouts в моем компоненте. Есть ли более простой способ уничтожить их всех? Может быть, с takeUntil (destroy $)?

  • 0
    если вам нужен удобный способ сделать takeUntil (destroy $), вы можете проверить этот вопрос: stackoverflow.com/questions/40737752/…
  • 0
    Спасибо, но я думаю, что, поскольку вы не можете подписаться на setTimeout, вы не можете использовать takeUntil (destroy $). Кроме того, указанная вами ссылка усложняет удаление подписок. Вам не нужны декораторы, вам просто нужен предмет: private destroy $ = new Subject (); ngOnDestroy () {this.destroy $ .next (); }
Показать ещё 3 комментария
Теги:
angular
settimeout
rxjs

2 ответа

5
Лучший ответ

мне нужно отказаться от подписки на вызовы 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));

При таком подходе вам не понадобятся несколько переменных для хранения различных идентификаторов таймаута, и вы можете быть уверены, что все ваши тайм-ауты будут очищены правильно, если вы всегда push возвращаемое значение setTimeout в вашем массиве идентификаторов.

Примечание: вы всегда должны отменять вызовы setInterval и всегда отказаться от подписки на открытые подписки.

  • 1
    Что произойдет, если компонент будет удален до setTimeout ?
  • 0
    Спасибо за быстрый ответ, а также за указание, что для setInterval это необходимо. Я бы пропустил это. Открытые подписки я узнал о трудном пути, лол;)
Показать ещё 6 комментариев
1

Это зависит от того, что происходит внутри callback- setTimeout, но обычно они должны быть отписаны. Нет никакого способа, как они могли бы быть волшебным образом отписаны. Их обратные вызовы будут уволены любым способом и могут вызвать ошибки или нежелательные побочные эффекты.

Хорошей практикой является назначение тайм-аута где-то, по крайней мере, для целей тестирования. То, что должно быть сделано в ngOnDestroy, this.subTimeout.unsubscribe() предполагает, что тайм-аут выполняется через RxJS:

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

Способ, которым он может быть улучшен, зависит от того, для чего служат эти тайм-ауты.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню