Estoy tratando de escribir un simulacro de PubSub bastante simple (por favor, no juzgues) y me he encontrado con un comportamiento bastante extraño.
Básicamente tengo tres clases, un padre y dos hijos. El punto es que tienen que comunicarse entre ellos, pero, por alguna razón, están perdiendo la referencia (comentado en FakePubSub):
class FakePubSubTopic { private readonly topicName: string; private readonly notify: (topicName: string, ...args: any[]) => void; constructor(topicName: string, notify: (topicName: string, ...args: any[]) => void) { this.topicName = topicName; this.notify = notify; } publishMessage(msg: any) { this.notify(this.topicName, msg); } } class FakePubSubSubscription { private topicName: string; public onEventReceived: ((...args: any[]) => void) | undefined; constructor(topicName: string) { this.topicName = topicName; } on(event: string, onEventReceived: (...args: any[]) => void) { this.onEventReceived = onEventReceived; } } export default class FakePubSub { _subscription: FakePubSubSubscription | undefined; _topic: FakePubSubTopic | undefined; private notify(name: string, ...args: any[]) { // when topic.publishMessage is called, // _subscription doesn't exist at this point (is undefined) this._subscription?.onEventReceived?.(args); } topic(name: string) { this._topic = new FakePubSubTopic(name, this.notify); return this._topic; } subscription(name: string) { this._subscription = new FakePubSubSubscription(name); return this._subscription; } } Para que sea más fácil de entender, cada topic de tiempo. se llama publishMessage , que debería ejecutar la devolución de llamada definida dentro subscription . on
prueba de broma (se supone que falla, pero al menos se ejecuta):
it('works', done => { const pubSub = new FakePubSub(); const topic = pubSub.topic('potato'); const subscription = pubSub.subscription('potato'); subscription.on('message', messages => { const [first] = messages; strictEqual('hi', first); done(); }); topic.publishMessage({ data: 'hi', }); });