Angular 12升级后触发TypeError: teardown.unsubscribe is not a function问题求助
问题原因
这个报错是Angular 12配套的RxJS 7.x版本带来的销毁逻辑严格校验导致的:
- Angular 12默认将RxJS依赖从6.x升级到7.x,RxJS 7调整了Subscription的销毁逻辑,要求所有加入订阅销毁队列的teardown资源,要么是具备unsubscribe方法的合法Subscription实例,要么是可执行的销毁函数,否则调用unsubscribe时就会抛出你看到的
teardown.unsubscribe is not a function错误,这段逻辑是RxJS内部实现,所以你在项目代码里搜不到对应代码。 - 你代码中的四个订阅变量里,至少有一个不是合法的Subscription实例:比如赋值时误将Observable、Subject、普通对象/函数赋值给了订阅变量,可选链
?.只能判断变量本身非空,无法判断变量是否具备unsubscribe方法,调用时就会触发RxJS内部校验报错。
解决方案
- 先定位非法的订阅变量:在ngOnDestroy中打印四个变量的类型和结构,确认哪个变量不具备unsubscribe方法,修正它的赋值逻辑,确保只有subscribe()方法返回的Subscription实例才会赋值给这些变量。
ngOnDestroy(): void { // 加这段排查,输出为function的才是合法订阅 console.log('a', typeof this.aSubscription$?.unsubscribe, this.aSubscription$) console.log('b', typeof this.bSubscription$?.unsubscribe, this.bSubscription$) console.log('c', typeof this.cSubscription$?.unsubscribe, this.cSubscription$) console.log('d', typeof this.dSubscription$?.unsubscribe, this.dSubscription$) // 原有逻辑 this.aSubscription$?.unsubscribe(); this.bSubscription$?.unsubscribe(); this.cSubscription$?.unsubscribe(); this.dSubscription$?.unsubscribe(); }
- 如果你用了Subscription的add方法统一管理多个订阅,确保add方法传入的参数只能是合法Subscription实例或销毁函数,不能传入普通对象、null、Observable等不符合要求的内容。
- 更安全的修复方案:改用takeUntil自动管理订阅生命周期,避免手动维护大量订阅变量:
// 组件内声明销毁触发器 private destroy$ = new Subject<void>(); // 所有订阅都加takeUntil操作符 this.userService.getUser().pipe( takeUntil(this.destroy$) ).subscribe(user => { /* 业务逻辑 */ }) // ngOnDestroy仅需要触发销毁信号 ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); }
- 临时兼容方案:给每个unsubscribe调用加上类型校验,避免非法调用:
function safeUnsubscribe(sub: any): void { if (sub && typeof sub.unsubscribe === 'function') { sub.unsubscribe(); } } ngOnDestroy(): void { safeUnsubscribe(this.aSubscription$); safeUnsubscribe(this.bSubscription$); safeUnsubscribe(this.cSubscription$); safeUnsubscribe(this.dSubscription$); }
内容的提问来源于stack exchange,提问作者Marcell
相关产品推荐
相关产品推荐

