我如何确保我取消订阅?
How do I make sure that I unsubscribed subscribe?
我有一个订阅,我从商店获取一些消息以输出 toastr。
我通过订阅.unsubscribe()
退订了。
如何检查我是否真的退订了?
subscription!: Subscription;
ngOnInit(): void { }
toastrError(): void {
this.subscription = this.store.select(getMessage).subscribe(m => {
(m.message && m.title) ? this.toastr.error(m.message, m.title) : null;
});
}
singIn(): void {
this.toastrError();
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
我猜如果不再出现错误提示,您可能会看到您已取消订阅。但我明白你的意思。您可以记录 ngOnDestroy 方法以确保它 运行 并因此取消订阅。
或者您可以使用我提出的演示之类的东西来调试它 here。通过 showing/hiding 子组件,您可以看到正在记录 'ping' 消息的订阅,相应地启动和停止。
- 一开始不要这样写使用服务
- 您可以像本例中那样使用 takeUntil。
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';
@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject();
constructor(private booksService: BookService) { }
ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));
this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
组件实例的生命周期始于 Angular 实例化组件 class 并呈现组件视图(及其子视图)。生命周期继续进行一些更改检测,因为 Angular 检查以查看数据绑定属性何时更改,并在需要时更新视图和组件实例作为响应。当 Angular 实际销毁组件实例并从 DOM 中删除其呈现的模板时,生命周期结束,因此 ngOnDestroy
在 Angular 销毁组件(或指令)之前立即被调用.
如果你想确认取消订阅是否真的发生,你可以在ngOnDestroy
方法中添加一个日志,或者在浏览器中调试它。
我认为您可以在 unsubscribe()
之后使用 closed
标志来验证它。例如
if(!this.subscription.closed)
console.error("Some error unsubscribing ?!");
如果您的意思是在组件外部进行验证,那么您可能无法执行此操作,因为 ngOnDestroy
只会在组件实例销毁之前调用。您可能会尝试在此处发出事件,但可能会迟到检查它!
但是,作为一种好的做法,您可以在组件中定义一个 subject
,并使用它来取消所有使用 takeUntil()
的订阅。例如
export class LoginComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get("http://whatever")
.pipe(takeUntil(this.destroy$))
.subscribe(value => console.log(value));
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
检查此问题以了解这些方法之间的区别
我有一个订阅,我从商店获取一些消息以输出 toastr。
我通过订阅.unsubscribe()
退订了。
如何检查我是否真的退订了?
subscription!: Subscription;
ngOnInit(): void { }
toastrError(): void {
this.subscription = this.store.select(getMessage).subscribe(m => {
(m.message && m.title) ? this.toastr.error(m.message, m.title) : null;
});
}
singIn(): void {
this.toastrError();
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
我猜如果不再出现错误提示,您可能会看到您已取消订阅。但我明白你的意思。您可以记录 ngOnDestroy 方法以确保它 运行 并因此取消订阅。
或者您可以使用我提出的演示之类的东西来调试它 here。通过 showing/hiding 子组件,您可以看到正在记录 'ping' 消息的订阅,相应地启动和停止。
- 一开始不要这样写使用服务
- 您可以像本例中那样使用 takeUntil。
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';
@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject();
constructor(private booksService: BookService) { }
ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));
this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
组件实例的生命周期始于 Angular 实例化组件 class 并呈现组件视图(及其子视图)。生命周期继续进行一些更改检测,因为 Angular 检查以查看数据绑定属性何时更改,并在需要时更新视图和组件实例作为响应。当 Angular 实际销毁组件实例并从 DOM 中删除其呈现的模板时,生命周期结束,因此 ngOnDestroy
在 Angular 销毁组件(或指令)之前立即被调用.
如果你想确认取消订阅是否真的发生,你可以在ngOnDestroy
方法中添加一个日志,或者在浏览器中调试它。
我认为您可以在 unsubscribe()
之后使用 closed
标志来验证它。例如
if(!this.subscription.closed)
console.error("Some error unsubscribing ?!");
如果您的意思是在组件外部进行验证,那么您可能无法执行此操作,因为 ngOnDestroy
只会在组件实例销毁之前调用。您可能会尝试在此处发出事件,但可能会迟到检查它!
但是,作为一种好的做法,您可以在组件中定义一个 subject
,并使用它来取消所有使用 takeUntil()
的订阅。例如
export class LoginComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get("http://whatever")
.pipe(takeUntil(this.destroy$))
.subscribe(value => console.log(value));
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
检查此问题以了解这些方法之间的区别