Javascript 角度-下面的EventEmitter服务是如何工作的?

Javascript 角度-下面的EventEmitter服务是如何工作的?,javascript,angular,Javascript,Angular,在我的工作中,我们一直在使用下面的服务来订阅和发出通知。作为一名初级开发人员,我已经了解角度传感器的输入和输出以及发射器的工作原理 但这项服务让我很困惑。开发这项服务的开发人员已经离开了公司,因为这段代码几乎是所有项目的样板,我不能问他它到底是如何工作的 特别是这一行:私有静态发射器:{[notificationName:string]:EventEmitter}={} import { Injectable } from '@angular/core'; import { EventEmitt

在我的工作中,我们一直在使用下面的服务来订阅和发出通知。作为一名初级开发人员,我已经了解角度传感器的输入和输出以及发射器的工作原理

但这项服务让我很困惑。开发这项服务的开发人员已经离开了公司,因为这段代码几乎是所有项目的样板,我不能问他它到底是如何工作的

特别是这一行:私有静态发射器:{[notificationName:string]:EventEmitter}={}

import { Injectable } from '@angular/core';
import { EventEmitter } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class EventEmitterService {

    private static emitters: { [notificationName: string]: EventEmitter<any> } = {}

    static get(notificationName: string): EventEmitter<any> {
        if (!this.emitters[notificationName])
            this.emitters[notificationName] = new EventEmitter<any>();
        return this.emitters[notificationName];
    }
}

/** 
to SUBSCRIBE:

private subscriptions = new Subscription();   
constructor(){
    this.subscriptions.add( EventEmitterService.get("notification_name").subscribe(payload => this.notificationHandler(payload)) );
}

TO EMIT: 

EventEmitterService.get("notificationName").emit(payload); 

to UNSUBSCRIBE:

ngOnDestroy(){
    this.subscriptions.unsubscribe();
}
*/

事件发射器模型基本上遵循可观察模式。在上面的代码中,我创建了一个静态发射器,这意味着我们可以在没有类实例的情况下调用它。因此,这将给我们带来一种类似效用的行为。你只需要了解一件事。发射器不断地监听事件,当事件发生时,它们会发出响应,不管成功与否。这个响应非常类似于操作系统中硬件产生的中断,它使CPU监听特定的中断,而不是执行其他任务。因此,当我们有一个更新in-out事件时,EventEmitter将广播该更改,我们的侦听器将在该特定事件上检测到它

我经常看到这种在服务中使用的模式
EventEmitter
不是服务中使用的。它用于将自定义事件从组件发送到其父组件

是RxJS的接口扩展。如果服务中需要多播可观察对象,则可以使用RxJS
Subject
(或
BehaviorSubject

在您的例子中,
emitter
变量是一个具有属性
notificationName
的对象,该属性将指向发射器

我也不明白这里的
静态
的含义。该服务已成为带有
{providedIn:'root'}
参数的单例。不会有多个
发射器的实例

您还可以对以下内容具有相同的行为

从'rxjs'导入{Subject};
私有发射器:{[notificationName:string]:Subject}={};
私有静态发射器:{[notificationName:string]:EventEmitter}={}
这一行仅仅意味着
emitters
是类型对象的
EventEmitterService
类的内部属性,其键是字符串,值是
EventEmitter
的实例。它被用来跟踪活动订阅。 服务的消费者与其他消费者无关,他们只想
发出
订阅
给定的通知,这就是它是私有的原因

如果您查看该界面,您将看到您确实可以
emit
subscribe
。发出时,您将发送一个有效负载,该有效负载将作为参数传递给订阅的函数使用者

当您订阅一个
EventEmitter
时,它会返回一个订阅,然后您可以
取消订阅该订阅。

当您将您的
EventEmitter
订阅添加到
subscriptions
时,您可以通过调用其
unsubscribe

一次取消订阅所有订阅,这与
发射器的类型为
EventEmitter
的任何其他服务类似。什么让人困惑?另一方面,为什么感觉像是我三年前写的代码:DHow它是如何工作的<代码>私有静态发射器:{[notificationName:string]:EventEmitter}={}
这是什么:
发射器
是对象类型吗?好吧,我想。但是关于这个
[notificationName:string]
呢?是否在方括号内…:?这仅仅意味着类型是一个对象,其中键是一个字符串(notificationName是一个别名),值是一个EventEmitter实例,请查看Typescript的文档:我用打印和新代码编辑了这个问题。但是出现了一个错误:/getter的返回类型也应该更改为
Observable
。Try:
static get(notificationName:string):可观察的
它起作用了,但用法完全相同。除了在类构造函数上实例化EventEmitterService之外,不需要重写吗?我假设这是一种比另一种更具“角度”的方式?基本功能是相同的。这是一种更有角度的做事方式。但是,您需要根据它调整整个服务。例如,上述退货类型问题。您需要相应地调整服务中的所有类型。
import { Subject } from 'rxjs';

private emitters: { [notificationName: string]: Subject<any> } = { };
import { Injectable } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { Subject, Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class EventEmitterService {

    // private static emitters: { [notificationName: string]: EventEmitter<any> } = {}
    private  emitters: { [notificationName: string]: Subject<any> } = {};


    get(notificationName: string): Observable<any>{
        if (!this.emitters[notificationName])
            this.emitters[notificationName] = new EventEmitter<any>();
        return this.emitters[notificationName];
    }
}