You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 16中Unsubscribe is not a function错误的原因及解决方法

错误原因与修正方案

错误原因

你遇到的TypeError: this.getMsgSubscription.unsubscribe is not a function错误,核心问题是:

  • 你的getMsg方法声明返回RxJS Subscription,但实际返回的是socket.io的on()方法的结果——这个结果是一个移除监听的普通函数,并非Angular RxJS标准的Subscription对象。
  • 当你把这个普通函数赋值给getMsgSubscription后,调用unsubscribe()自然会报错,因为该函数没有这个方法。

修正步骤

1. 重构Service代码:将Socket事件包装为RxJS Observable

把socket.io的事件监听逻辑包装成RxJS Observable,这样订阅后就能得到标准的Subscription对象,同时正确实现取消监听的逻辑:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class Sockservice {
  // 假设this.socket是已初始化的socket.io客户端实例

  getMsg(users_data: any): Observable<any> {
    return new Observable(observer => {
      // 定义socket事件的处理函数
      const messageHandler = async (data: any) => {
        if (users_data.user1._id === data.sender_id && users_data.user2._id === data.reciever_id) {
          const container = document.getElementById('chat-container');
          const element = document.createElement('ul');
          if (this.msg !== data.message) {
            element.innerHTML = data.message;
            element.style.textAlign = 'right';
            container?.appendChild(element);
          }
        }
      };

      // 注册socket事件监听
      this.socket.on('loadNewChat', messageHandler);

      // 返回取消订阅的清理逻辑:移除socket事件监听
      return () => {
        this.socket.off('loadNewChat', messageHandler);
      };
    });
  }
}

2. 调整Component代码:正确订阅Observable

在组件中订阅Observable,得到标准的Subscription对象,在组件销毁时调用unsubscribe():

import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
import { Subscription } from 'rxjs';
import { Sockservice } from './path-to-your-service';
// 假设你用的是MatDialog,引入对应的依赖
import { MAT_DIALOG_DATA } from '@angular/material/dialog';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponent implements OnInit, OnDestroy {
  private getMsgSubscription?: Subscription;
  dialogdata: any;
  UserData: any = { sender_id: '', reciever_id: '' };

  constructor(
    private sockservice: Sockservice,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {}

  ngOnInit(): void {
    this.dialogdata = this.data;
    this.UserData.sender_id = this.dialogdata.user2._id;
    this.UserData.reciever_id = this.dialogdata.user1._id;
    
    // 订阅Observable,获得标准Subscription
    this.getMsgSubscription = this.sockservice.getMsg(this.dialogdata).subscribe();
    
    this.sockservice.getChats(this.UserData);
  }

  ngOnDestroy(): void {
    // 安全调用unsubscribe,避免空值报错
    this.getMsgSubscription?.unsubscribe();
  }
}

额外优化建议

  • 避免直接操作DOM:Angular推荐通过数据绑定渲染视图。可以将消息存入组件数组,用*ngFor动态渲染,而非直接appendChild。
  • 类型安全:不要用any类型,定义User、ChatMessage等接口,提升代码可维护性。

内容的提问来源于stack exchange,提问作者themadhatter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:53:14