So I've attached two events if someone screams, they are called synchronously, why so?
const events = require('events');
const eventEmitter = new events.EventEmitter();
eventEmitter.on('scream', function() {
console.log("Screaming");
});
eventEmitter.on('scream', function(name) {
console.log(name+" is screaming");
});
eventEmitter.emit('scream', 'Bob');
O/P:
Screaming
Bob is screaming
Because in nodejs, The event loop is single threaded and pick one event at a time and treat those events independently.
In your case, there are two event handler with the same name, so when event loop gets the eventEmitter.emit('scream', 'Bob') it sends the particular event handler.
When first event handler done with it, Now it goes to the second handler because with the same name.
It follow the FIFO but if you use emitter.prependListener(eventName, listener) then it will be executed first the FIFO.
You should know, if you want to call only one time then you should use eventEmitter.once('scream') It will be called only one time.
eventEmitter.once('scream', function() {
console.log("Screaming");
});
eventEmitter.emit('scream', 'Bob');
eventEmitter.emit('scream', 'Bob');
eventEmitter.emit('scream', 'Bob');
Output: Screaming // Only one time.
Because the Event loop fetches events from Event Queue and sends them to call stack one by one.
And Event Queue is FIFO (First-In-First-Out)
Related
I am writing a crypto trading bot that is required to listen to websocket streams (orderbook changes, trade executions etc.). On every event, the websocket should save the incoming message in an array and call the main logic loop to process the message.
While the logic code is executing, if more messages are received, they should be queued up in an array (saved somewhere) and they should not immediately call up the main loop. Idea is that once main loop is done with the processing, it can look up the queue array and pick the next message to process. This way no messages will be lost. Also main logic loop won't be called multiple times if multiple messages arrive while it is already working.
I am using the following code but not able to achieve the desired architecture.
webSocket.onopen = function(event) {
var msg = {
"op": "authKeyExpires",
"args": ["somekey", nonce, signature + ""]
};
webSocket.send(JSON.stringify(msg));
webSocket.send(JSON.stringify({"op":"subscribe", "args":["orderBookApi:BTCPFC_0"]}));
};
webSocket.onmessage = async function(e) {
queue.push(JSON.parse(e.data));
main_logic(queue);
}
async function main_logic(queue){
//process the next message in the queue and then delete it. Keep doing it till queue is empty.
}
I have read that maybe forking or worker process for websocket can help. Kindly advise as I am new to node js and programming in general.
Why is order of listener should be on top of emitter?
const EventEmitter=require('events');
const emitter=new EventEmitter();
//Register a Listener
emitter.on('messageLogged',function(){
console.log('Listener Called');
})
//Raise an event
emitter.emit('messageLogged');
Because you need to subscribe a listener to the event before you emit an event.
The idea is that when you call emit it will call functions you attached to the event. If there is no function it will call nothing. You can not call a function that is attached in the future for an event that you emit at the moment.
I use socket.io in Node.js.
var rooms = {"a", "b"};
io.on('connection', function(client) {
socket.on('room', function(room) {
if(room in rooms){
socket.join(room);
}
});
});
...Code below...
Will block condition the main thread and process below:
if(room in rooms){
socket.join(room);
}
I mean, will code below wait the process upper due condition if?
There's nothing in your code that waits or blocks the main thread. Both io.on() and socket.on() are just installing event handlers. The rest of your Javascript continues to run and those event handlers will be called some time in the future when the event they are associated with occurs.
The conditional:
if(room in rooms){
is evaluated at the moment that code runs and immediately executes. It doesn't wait for anything or block.
We could probably help you better if you told us what the actual problem is that you're trying to solve.
I have two .js file. One emits the event and another listens for it. The code looks as below.
Emitter
var EventEmitter = require('events').EventEmitter;
utils.inherits(ConfigFileManager, EventEmitter);
var manager = new ConfigFileManager();
var watcher = chokidar.watch(CONFIG_DIR, {persistent: true});
watcher.on('add', function (path) {
manager.emit('monitor', 'print this data');
});
watcher.on('change', function (path) {
console.log('change event fired');
manager.emit('monitor', 'print this data');
});
module.exports = manager;
The chokidar.watch keeps the event queue and restricts node from exiting. Now, listener is in different file, as given below.
Listener
var manager = require('./emitter');
manager.on('monitor', function(data) {
console.log(data);
});
and I run "node listener.js". The first time "add" event calls the listener, and all is fine. However when I change a file, the event is emitted, but the listener never gets it. If I add a setTimeout at the end of the listener.js, the listener is getting events until the timeout expires. So, once the listener script completes, the events are not received. How can I make the listener to listen forever?
Also, if I keep the listener code also in emitter.js, then it works, because chokidar.watch keeps the script from terminating. But, I want to keep them separate for better organization.
I would like to use an event in node.js to execute some code; my question is, what is the scope of the invoked event code? Specifically, does it share the scope of the event invoker, or is it "isolated"? I know that I can pass parameters to the code invoked on the event to achieve a similar effect, but ideally I'd like to have the invoking scope available.
The event is tied to the scope of the invoker. i.e. an EventEmitter exported from a module, can only be used to listen for events emitted from that same EventEmitter.
Nodejs EventEmitter - Define scope for listener function
When you emit an event, you put it into a queue to be processed later by the node event system. Any variables from the scope where the event is emitted must be passed to emit as arguments. When node takes that event and triggers all bound callbacks, that happens under both a distinct "clean" scope and a distinct "clean" stack. (Side note, this is why stack traces in node can be a nuisance for debugging).
var events = require('events');
var myEmitter = new events.EventEmitter();
function closure1(word, number) {
function closure2(animal, vegetable) {
myEmitter.emit('hey', word, number, animal, vegetable, 43);
}
closure2("horse", "carrot");
}
myEmitter.on('hey', function (word, number, animal, vegetable, anotherNumber) {
console.log('hey event fired with', word, number, animal, vegetable, anotherNumber);
});
closure1("table", 42);
When you run that, it will print "hey event fired with table 42 horse carrot 43".
see the node.js docs on emitter.emit(event, [arg1], [arg2], [...]