首页 > 解决方案 > 什么决定了 Socket IO 的 Angular 区域

问题描述

我在 Angular 服务中使用 SocketIO 时遇到了一个有趣的问题。

案例 1:作为服务属性的
套接字当我在服务类上实例化套接字时,来自套接字的所有响应都在角度区域中完成,并且 UI 将相应地更新。

import { io } from 'socket.io-client/build/index';
import { Injectable, NgZone } from '@angular/core';

@Injectable() {
export class MyService {
  private socket = io("localhost:3000")
  
  dealCards(): void {
    this.socket.emit('deal_cards')
  }

  recieveStartingCards(): Observable<GameState> {
    const observable = new Observable<GameState>((observer) => {
      this.socket.on('dealt_cards', (data: GameState) => {
        console.log('IN ZONE', NgZone.isInAngularZone()); // returns true
        observer.next(data));
        return () => this.socket.disconnect();
      });
    });
    return observable;
  }

案例 2:作为常量
的套接字当我将套接字实例化为常量并在服务类中引用它时。套接字通信发生在角度区域之外,UI 只会在您使用时更新ngZone.run()

import { io } from 'socket.io-client/build/index';
import { Injectable, NgZone } from '@angular/core';

const socket = io("localhost:3000")

@Injectable() {
export class MyService {
  constructor(private ngZone: NgZone) {}
  private socket = socket
  dealCards(): void {
    this.socket.emit('deal_cards')
  }

  recieveStartingCards(): Observable<GameState> {
    const observable = new Observable<GameState>((observer) => {
      this.socket.on('dealt_cards', (data: GameState) => {
        console.log('IN ZONE', NgZone.isInAngularZone()); // returns false
        observer.next(data));
        return () => this.socket.disconnect();
      });
    });
    return observable;
  }

我的问题是为什么案例 1 中的套接字通信总是在角度区域中,为什么案例 2 中的套接字通信从不在角度区域中?

标签: angularsocketssocket.io

解决方案


Angular zone 在引导Angular 应用程序的阶段开始发挥作用。DI(依赖注入)系统中涉及的所有 Angular 服务都在此NgZone.run调用中实例化。

在第一种情况下,您使用套接字作为属性。这意味着它将在服务构造函数中实例化,并且在引导过程之后发生。

在第二种情况下,io当没有定义 Angular 区域时,您在引导应用程序之前进行初始化。


推荐阅读