I am new to nodejs programming. so be patient with me.
I have two nodejs modules. One passes passes a message to another nodejs module. the second processes it and pass result back
to the first module.
method 1
first module
:
secondModule.callFunction(message, function(data){
//deal with the return message from the second module
})
:
second module
:
function callfunction(message, callback){
//asynchornous functions for processing
callback(data);
}
:
method 2
same thing but done using event emitters in the second module
first module
:
secondModule.callFunction(message){
})
secondModule.on('done_event', function(data){
//deal with the reply
});
:
second module (uses event emitter)
:
function callFunction(message){
//asynchornous functions for processing
self.emit('done_event', data);
}
:
Are they both correct. what is the difference in these things (both are asynchornous)
or have i done something stupid.
Thanks in advance
Differences between plain callbacks and EventEmitter events (which is node's implementation of publisher-subscriber pattern)
You can attach multiple listeners to same event. Callbacks are one-to-one notifications, events - one-to-many.
You can't return value from event. Events are one way messages.
Often, callbacks follow (error, data1, data2, data3, ...) signature because single callback responsible for normal and error data flow (and async libraries usually expect this behaviour)
EventEmitter-based api, on the other hand tend to separate error and non-error messages
"error" event is special in event emitter: if there is no listener for it, EventEmitter throws an exception. With callbacks it's your responsibility to check first error parameter.
In your example both approaches are valid.
My understanding of events is that events are used when you want to "break" up your processing in pieces, and/or you don't really know when things are happening. So if your callFunction was a long running task (e.g. doing or waiting a lot for IO), you could break it into pieces and submitting, for instance, data events while it's processing, and then finish with a done event. However, if it's merely a "normal" function call, I would simply use a callback.
I'd say events are for plain notifying when an emitter tells everyone interested about some thing happened. It doesn't care what they will do with this fact, it just tells and forgets. Of course you can return a value from an event (by changing fields of an object provided in parameters) but this looks ugly, non-robust and not logical having in mind that event model presumes multiple listeners.
Callbacks OTOH are for requesting a value. You call for user's help with some data and require result.
For example:
Event - server.on('connection'). Client connected, you tell about it and forget.
Callback - server.isIPAllowedCallback(socket): Boolean. There's a client, you want to check if this IP is allowed.
Main reason for this difference is bubbling event model with multiple listeners. In languages where you just use one listener like someObject.onSomeEvent = someEventHandler there's no difference between handlers and callbacks.
Related
I am using Ionic2 with Meteor. I observe a Cursor, for when it gets added to or updated.
public messages: Mongo.Cursor<Message>;
this.messages.observe({
added: (message) => this.addMessageToLocal(message),
changed: (message) => this.updateMessageToLocal(message)
});
In my case, the added event gets triggered before the changed event. However, they run asynchronously. I would like the event that is triggered first (added) to finish before the next event (changed) starts.
Is this possible?
Thank you
UPDATE
I am thinking of maintaining a flag, that says when one job is busy, and the other one must wait until it is finished. Is this advisable?
In the asynchronous world of javascript you cannot control (much as you would like to) the order of execution.
There are two ways to deal with this
1) Get used to it, and write your code accordingly
2) Do the first thing, and then start the second thing in the callback response for the first thing (although in this case I don't think you can)
Scenario :- a json with checked & unchecked item count needs to be sent to a common function which in turn does some basic validation or shows error. There are different function each handle by different css/js team which call this function & depending on the common function result (true/false) each team/module that provided the json with check/uncheck status does the relevant action. Thus both common function (say getcount) & every independent team calling this function rely on the result of common function manipulate the dom/css independently & the common function too manipulate dom independently.
Instead of conventional way of calling function (say getCount({"chk" : 2 , "unchk" : 4})) i am looking for pusblish/subcribe method which is more cleaner as in Jquery & easy to convey to all as only topic name & contract/json needs to describe (also less if/else clause). Since common function is subscriber & when every independent function publishes the resultant chk/unchek json the common function can easily do the manipulation using the publish/subscribe approach but the independent method has to do counter action as well which is only possible if subscribe function can send the result. I know javascript is asynchronous also i understand that common method can publish (say "resultOfGetCount") which every independent function/module can listen to & do the action but is there any way in either in plain javascript or jquery where in on which subscriber can send the publisher the result in a way similar to $.ajax where in the callback function is called once server call is complete.
Looking for the best approach for such scenario.
Here's a simple publish subscribe model in jQuery from this blog post
var exampleHandle = function(){
//do stuff when topic is published
...
}
function subscribe(topic,handle){
$("#subscription").bind(topic,handle);
}
function publish(topic,params){
$("#subscription").trigger(topic,params)
}
function unsubscribe(topic,handle){
$("#subscription").unbind(topic,handle);
}
where you can use a simple string as a topic to subscribe or unsubscribe to the topic, and attach the handle as a callback function. The handle can also be used to unsubscribe from the topic later if necessary.
The method is based on jQuery’s trigger and bind functions. These
allow you to listen for a custom event on an element, and manually
trigger an event on an element. This provides the basic backbone for
the simple subscription model.
If an application element wants to
subscribe to a topic, they bind a handler to the “subscription
element”. This can be a designated element on the page, or just the
window element. You can also of course use different elements for
different subscriptions. Then, when something publishes to that topic,
the handler function will execute.
For publishing, a function can pass
a topic and parameters to the publish function. This calls jQuery’s
trigger to set off the event topic, passing along the parameters.
These params are passed to the handle function.
If an element wants to
cancel its subscription, they can pass the topic and handle function
to the unsubscribe method. Note that the handle has to be the same
function object that was used to originally subscribe, not a copy or
similar function. You also can use jQuery’s unbind to cancel all
subscriptions to a topic by only specifying the topic without the
handle function.
Node.js approach is event driven and I was wondering how would you tackle the problem of when to fire off an event?
Lets say that we have some actions on a web application: create some data, serve pages, receive data etc.
How would you lay out these events? In a threaded system the design is rather "simple". You dedicated threads to specific set of tasks and you go down the road of thread synchronization. While these task are at low on demand the threads sit idle and do nothing. When they are needed they run their code. While this road has issues it's well documented and kind of solved.
I find it hard to wrap my head around the node.js event way of doing things.
I have 10 request coming in, but I haven't created any data so I can't serve anying, creating data is a long action and another 5 client wants to send data. What now?
I've created the following untested code which is basically a pile of callbacks which get registered and should be executed. There will be some kind of a pile manager that will run and decide which code does it want to execute now. All the callback created by that callback can be added "naturally" to the even loop. It should also register it's self so the event loop could give the control back to it. Other things like static content and what ever can be bound differently.
How can I register a call back to be the last call in the current event loop state?
Is this a good way to solve this issue?
The most important thing to remember when coming from a threaded environment is that in node you don't wait for an action to finish happening, instead you tell it what to do when it is done. To do this you use a callback, this is a variable which contains a function to execute, or a pointer to a function if you like.
For example:
app.get('/details/:id?', function (req, res) {
var id = req.params.ucid,
publish = function (data) {
res.send(data);
};
service.getDetails(id, publish);
});
You can then invoke the publish method from within your get details method once you have created the required data.
getDetail : function (id, callback) {
var data = makeMyData(id);
callback(data)
}
Which will then publish your data back to the response object. Because of the event loop node will continue to serve requests to this url without interrupting the data generation from the first request
The answer chosen is the most correct, there is but one minor code change and that is:
Change this function from this:
getDetail : function (id, callback) {
var data = makeMyData(id);
callback(data)
}
To that:
getDetail : function (id, callback) {
var data = makeMyData(id);
setTimeout(callback, 0, data);
}
Update 2019:
In order to comply with community standard I've broken off an update to a new answer.
I've used setTimeout because I wanted to defer the callback to the back of the event loop. Another option I've used was process.nextTick(), this helped to defer the callback to the end of the current event processed.
For example:
getDetail : function (id, callback) {
var data = makeMyData(id);
process.nextTick(((info)=> callback(info))(data))
}
I have seen process.nextTick used in a few places and can't quite tell what it's being used for.
https://github.com/andrewvc/node-paperboy/blob/master/lib/paperboy.js#L24
https://github.com/substack/node-browserify/blob/master/index.js#L95
What are the main/proper use cases of process.nextTick in Node.js? The docs basically say it's a more optimized way of doing setTimeout, but that doesn't help much.
I used to do a lot of ActionScript, so the idea of "waiting until the next frame" to execute code makes sense on some level - if you're running an animation you can have it update every frame rather than every millisecond for example. It also makes sense when you want to coordinate setting a bunch of variables - you change the variables in frame 1, and apply the changes in frame 2. Flex implemented something like this in their component lifecycle.
My question is, what should I be using this for in server-side JavaScript? I don't see any places right off the bat where you'd need this kind of fine-tuned performance/flow control. Just looking for a point in the right direction.
process.nextTick puts a callback into a queue. Every callback in this queue will get executed at the very beginning of the next tick of the event loop. It's basically used as a way to clear your call stack. When the documentation says it's like setTimeout, it means to say it's like using setTimeout(function() { ... }, 1) in the browser. It has the same use cases.
One example use case would be, you create a constructor for some object that needs events bound to it. However, you can't start emitting events right away, because the code instantiating it hasn't had time to bind to events yet. Your constructor call is above them in the call stack, and if you continue to do synchronous things, it will stay that way. In this case, you could use a process.nextTick before proceeding to whatever you were about to do. It guarantees that the person using your constructor will have time enough to bind events.
Example:
var MyConstructor = function() {
...
process.nextTick(function() {
self._continue();
});
};
MyConstructor.prototype.__proto__ = EventEmitter.prototype;
MyConstructor.prototype._continue = function() {
// without the process.nextTick
// these events would be emitted immediately
// with no listeners. they would be lost.
this.emit('data', 'hello');
this.emit('data', 'world');
this.emit('end');
};
Example Middleware using this constructor
function(req, res, next) {
var c = new MyConstructor(...);
c.on('data', function(data) {
console.log(data);
});
c.on('end', next);
}
It simply runs your function at the end of the current operation before the next I/O callbacks. Per documentation you can use it run your code after the callers synchronous code has executed, potentially if you can use this to give your API/library user an opportunity to register event handlers which need to be emitted ASAP. Another use case is to ensure that you always call the callbacks with asynchronously to have consistent behaviours in different cases.
In the past process.nextTick would be have been used provide an opportunities for I/O events to be executed however this is not the behaviour anymore and setImmediate was instead created for that behaviour. I explained a use case in the answer of this question.
"Every callback in this queue will get executed at the very beginning of the next tick of the event loop" is not correct. Actually, nextTick() runs right after completing the current phase and before starting the next phase. Minute details are important!
A function passed to process.nextTick() is going to be executed on the current iteration of the event loop, after the current operation ends. This means it will always execute before setTimeout and setImmediate.
Understanding setImmediate()
I am trying to understand the purpose of addListener in node.js. Can someone explain please? A simple example would be:
var tcp = require('tcp');
var server = tcp.createServer(function (socket) {
socket.setEncoding("utf8");
socket.addListener("connect", function () {
socket.write("hello\r\n");
});
socket.addListener("data", function (data) {
socket.write(data);
});
socket.addListener("end", function () {
socket.write("goodbye\r\n");
socket.end();
});
});
server.listen(7000, "localhost");
Due to the fact that Node.js works event-driven and executes an event-loop, registering listeners allow you to define callbacks that will be executed every time the event is fired. Thus, it is also a form of async. code structuring.
It's comparable to GUI listener, that fire on user interaction. Like a mouse click, that triggers an execution of code in your GUI app, your listeners in your example will be run as soon as the event happens, i.e. a new client connects to the socket.
it registers a listener for an "event". Events are identified by strings, such as "connect" and "data". the second argument is a function, a so called "callback", also refered to as "event handler". Whenever a specific event occurs within the object the listeners have been registered to, all handlers are invoked.
node.js uses this, because it employs an asynchronous execution model, that can best be handled with an event-driven approach.
greetz
back2dos