-
• #2
Hm.. For whatever reason, it works now.. I'm a bit embarrassed.. Just for reference, code is here:
function aClass() {}; aClass.prototype.testEmit = function() { setTimeout(()=>this.emit('TestEvent'), 1000); } var a = new aClass(); a.on('TestEvent', ()=>console.log('Got event')); a.testEmit(); // get 'Got event' printed in log var a1 = new aClass(); a1.testEmit(); // event here is not caught
-
• #3
Sat 2021.03.27
@AndreyVS While searching for an answer to #1, our posts crossed:
Why can't I use this.emit(...)?
I'm now puzzled also, as:
ref: 'You cannot rebind this in an arrow function.'
violates ECMAScript specification:
https://stackoverflow.com/questions/33308121/can-you-bind-this-in-an-arrow-function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
It seems the L3()=>this.emit('TestEvent')
arrow function is bound to the setTiemout() object, or maybe this is bound to the application environment Global scope and not the L2 aClass.prototype.testEmit object as desired. This might explain why it just works, and not actually a specification violation.
Incidentatlly, Post #2 L1 should not terminate with a semi-colon, and L4 should. -
• #4
'However, I cannot emit an event within a prototype function with 'this''
After playing with these snippets, I'm now not entirely sure what the original intent is/was.
In post #2 L6, registers an arrow function response to object a
Missing, following L8 is the event listener registration for object a1
So when L9 executes, there isn't the registered listener to respond to the console.
'Thus if e.g. I have two step up modules, I cannot subscribe directly to each of them'
It is possible that as the second 'Got event' never occurs, (comment L9) compared to the test results in post #1 is just simply tripping up thinking, as there isn't a means (an on() method attached to a1) to view the second event?
-
• #5
Many thanks, Robin! However, seems that this correctly references the instance, also supported by stackoverflow answer:
Arrow functions do not have a this value of its own, when you access it, you are accessing the this value of the enclosing lexical scope.
We can see if we print it out:
function aClass(id) { this.id = id; } aClass.prototype.testEmit = function() { setTimeout(()=>{console.log('This is ', this); this.emit('TestEvent')}, 1000); }; var a = new aClass('a'); a.on('TestEvent', ()=>console.log('a emitted')); a.testEmit(); // get 'This is aClass {id = a...}' and the event is caught with 'a emitted' var a1 = new aClass('a1'); a1.on('TestEvent', ()=>console.log('a1 emitted')); a1.testEmit(); // get 'This is aClass {id = a1...}' and the event is caught with 'a1 emitted'
By contrast, if we replace arrow function in L6 with function(), this will reference the global object, which does not have emit(), and code crashes.
setTimeout(function(){console.log('This is ', this); this.emit('TestEvent')}, 1000); //crashes
To summarize for reference, this can be used, but should be cautious when calling setTimeout:
function aClass() {} aClass.prototype.testEmit = function() { this.emit('TestEvent'); }; var a = new aClass(); var a1 = new aClass(); a.on('TestEvent', ()=>console.log('a emitted')); a1.on('TestEvent', ()=>console.log('a1 emitted')); setTimeout(a.testEmit.bind(a), 500); // can use, get printed 'a emitted' setTimeout(()=>a1.testEmit(), 1000); // can use, get printed 'a1 emitted' setTimeout(a.testEmit, 1500); //crashes, as *this* in testEmit definition references global object, not a
Hi Everyone! On Puck I try to organize communication between objects with events (see Object.emit and discussion here). However, I cannot emit an event within a prototype function with 'this'. Thus if e.g. I have two step up modules, I cannot subscribe directly to each of them, and need to add either a module id as an event argument or additional empty object (see below).
In comments here is what I'd want:
Here is a way round with an empty object:
Why can't I use this.emit(...)?