Angular 9使用@ngneat/until-destroy npm包进行可观察对象的取消订阅

12

我正在使用@ngneat/until-destroy 这个 npm包来自动取消订阅observables。我已经使用了checkProperties:true来自动取消订阅observables。

但是,我不知道如何测试它。observable是否被取消订阅了?

我的问题很简单。这段代码有效吗?还是我必须像这样在订阅之前使用管道?

.pipe(untilDestroyed(this))

非常感谢您的提前帮助。

import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';

@UntilDestroy({ checkProperties: true })

@Component({
  selector: 'app-view-all-purchase',
  templateUrl: './view-all-purchase.component.html',
  styleUrls: ['./view-all-purchase.component.scss']
})

export class ViewAllPurchaseComponent implements OnInit, OnDestroy  {

  
  ngOnInit() {

 this.subscibe1 =  this.vendorService.five_vendors().subscribe(data => {
    if(data){
      console.log(data)
       this.vendor_list = data
    }})

}

ngOnDestroy() {
 
 }
 
}

你为什么想要取消订阅可观察对象?你何时想要取消订阅它? - user13258211
1
实际上,我已经阅读了一些关于由于可观察对象而导致的内存泄漏的文章。因此,在组件被销毁时即ngOnDestroy()方法中取消订阅可观察对象非常重要。 - pratik jaiswal
2
这对某些可观察对象是正确的,主要是自定义的可观察对象。如果您在 ngOnDestroy() 期间不取消订阅它们,它们将保留下来。使用 HttpClient 进行 HTTP 请求的那些可观察对象不需要被取消订阅,因为它们在请求完成时会自动取消订阅。 - user13258211
1
好的,谢谢。你用过 until destroy npm 包吗?checkproperties: true 有效吗,还是我需要使用 pipe(untildestroyed(this))? - pratik jaiswal
@user13258211,请不要传播错误信息,所有的可观察对象都需要取消订阅,即使是来自HttpClient的对象: https://github.com/angular/angular/issues/46542 - undefined
4个回答

3

要检查您的可观察对象是否已取消订阅,您可以将console.log添加到您的订阅中(您已经有了,但放在了if(data){} 之外),然后在ViewAllPurchaseComponent销毁后更改另一个组件中的可观察对象。如果在更改另一个组件中的可观察对象时从ViewAllPurchaseComponent获得console.log,则未取消订阅。

我不知道'@ngneat/until-destroy',我通常使用

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

希望这能帮到你!

我知道这种方法,但我不想用它。我想使用上述的npm包来自动取消订阅observables。 - pratik jaiswal
1
好的,现在你可以使用console.log检查observable是否已取消订阅。 - Amygdala
我也在寻找同样的东西。他们在 Github 存储库中提供的示例有效。 - HV Sharma
即使不使用与 OP 问题相关的包,手动取消订阅也容易出现错误和疏忽。您应该使用 rxjs takeUntil https://www.learnrxjs.io/learn-rxjs/operators/filtering/takeuntil - Mozgor
@Mozgor 如果你使用这个包中的管道,那么takeUntil是不必要的,这就是它的全部意义,替代takeUntiltake(1)和其他类似的管道。 - undefined
这正是我评论的要点:无论出于什么原因,如果有人拒绝使用“直到销毁”,手动取消订阅仍然是一个可行的解决方案。我同意“包”是我个人认为最好的解决方案,但在这里我们正在评论一个显示过时替代方法的答案。 - undefined

2
我通常这样使用untilDestroyed
this.subscibe1 =  this.vendorService.five_vendors()
**.pipe(untilDestroyed(this))**
.subscribe(data => {
if(data){
  console.log(data)
   this.vendor_list = data
}})

1

我这样使用它

import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
    
@UntilDestroy()
@Component({
  selector: 'app-view-all-purchase',
  templateUrl: './view-all-purchase.component.html',
  styleUrls: ['./view-all-purchase.component.scss']
})

export class ViewAllPurchaseComponent implements OnInit {
  ngOnInit() {
    this.subscibe1 = this.vendorService.five_vendors().pipe(
      untilDestroyed(this)
    ).subscribe(data => {
      if (data) {
        console.log(data)
        this.vendor_list = data
      }
    })
  }
}

0

最佳模式是使用异步管道

export class ViewAllPurchaseComponent {
  vendor_list$ = this.vendorService.five_vendors();

  constructor(private vendorService: VendorService) {}
}

并在模板中使用

<ng-container *ngIf="vendor_list$ | async as vendor_list">
  Vendor list is available here {{ vendor_list | json }}
</ng-container>

这是无关紧要的。用户可能不想在模板中取消订阅,这样异步管道就没有用了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接