Difference between dojo/on and dojo/aspect - javascript

In the dojo Javascript library, dojo/on and dojo/aspect are used as functions that listen to events.
However I don't see how they differ from one another. Can someone explain when you would use on and when you would use aspect?

dojo/on is used for listening to events. dojo/aspect is used to intercept calls to javascript functions.
With aspect, you can intercept a function call and do something before the function call, after, or both. With events, you are being notified that something occurred.
Technically, if the target object is not a domNode, dojo/on ends up calling aspect.after(...)
In <=1.6, there was not a distinction and dojo.connect was used. Functions were used to notify that an event occurred and there are still remnants of that in the code base. An example is using on with the click event on a dijit/Button.
dojo/Evented http://dojotoolkit.org/reference-guide/1.9/dojo/Evented.html

Related

What causes the Node.js EventEmitter warnings?

My node.js backend has a lot of mongoose.connection.useDb lines because it frequently needs to switch databases. Today I restarted my server and got this warnings:
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connected listeners added to [NativeConnection].
It took me some time to find a solution, and I found that by just adding mongoose.connection.removeAllListeners() the warning dissapears. What does this mean, and what exactly is an event? It feels like if I remove all listeners that the code that used those databases (like when I needed to create a model for a schema) shouldn't work anymore, but that isn't the case.
What does this mean?
This warning indicates that you're registering 11 or more listeners for the same event or calling some code that is internally causing this to happen. The warning is because normal usage of an event emitter rarely needs 11 listeners for the same event.
Instead, this many listeners for the same event is usually an indication that you're registering for the same event over and over or repeatedly calling some function that causes the same listener over and over again. In your specific case it looks like you should perhaps use the noListener: true option when calling .useDb(). See the doc here and this troubleshooting report.
Failing to remove listeners that you are no longer using can create a regularly growing memory leak (just like the error message indicates) because nodejs can't tell that you no longer intend to use that listener. It's still registered for the event, the event can still occur and thus the listener (the ones you no longer intend to use) are still active. This takes additional memory inside the eventEmitter object and (perhaps more importantly), it may keep certain closure variables from getting garbage collected inside the listener callback function/scope.
So, whenever an eventEmitter object gets the 11th or more listener for the same event, it issues this warning.
If you show the actual code and context where this warning occurs, we could give you more specific advice about what you should/should not be doing in that code. The above is a generic description/advice because you didn't show your specific code and context.
What is an event?
This warning comes from an eventEmitter object which, given your explanation, is probably being used inside the database whenever you call .useDb(). Something you are doing with the database is causing it to register a listener for an event on an eventEmitter object. If you want to know more about events in the context of an eventEmitter object, I'd suggest reading the eventEmitter documentation.
In a nutshell, an eventEmitter object allows one to listen for events by calling obj.addListener("someEventName", fn) or the identical (but shorter) obj.on("someEventName, fn) where obj is an instance of the EventEmitter class. Then, other code can trigger events obj.emit("someEventName", someData). When an event is triggered, all registered listeners for that specific event name will have their callback called. Nodejs uses event objects and listeners like this in lots of places in its libraries. For example streams use listeners to listener for incoming data as in stream.on('data', myCallback).

*When or why* would you use JavaScript's EventTarget?

I originally was reading this:
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
But, then I came upon this question here:
How to use JavaScript EventTarget?
However, when or why would a developer need to use EventTarget?
I'm still learning. I know the SO community doesn't like duplicate questions, but I feel this isn't since it's asking a different question than the one I cited above (it only discusses how to use it).
For the same reason you might use EventEmitter in node.js: you have some custom class/object which you would like to emit events.
Events are useful to allow your object to notify other parts of your code that something interesting has happened, without the object actually knowing anything about the code that uses it.
For example, a link on a page (implemented by the browser as an HTMLAnchorElement object) does not need to know what your code does in response to clicks; you simply register a click event handler (by calling EventTarget#addEventListener('click', …)) and when clicks happen, the browser internally calls EventTarget#dispatchEvent(new Event('click')) and your code handles the event.
Your own custom objects can use this pattern for a wide range of things. Perhaps you'd like to notify things that your object's data has changed -- either as a result of the user doing something or a fetch call returning.
This allows you to build code that is easily composable and testable: the emitter doesn't care who is listening or what that code does, and the consumers don't care about the implementation details of the event getting fired.

Should we consider the addEvenetListener method a loop?

As far as I understand, the addEvenetListener method will usually just listen to a certain event and when that event is triggered a callback function will be called to perform everything in the event handler code in that callback function.
addEventListener listens for each triggering of a certain event. To me it seems quite like a for each loop as initiated by the forEach() method.
I assume we could at least say both forEach() and addEvenetListener are loopish functions, though just functions (methods).
Javascript addEventListener follows the famous "don't call us, we will call you." Also known as the Hollywood principle.
In software engineering it's also called the observer or subscriber part as in the publisher/observer design pattern.
Basically when you call addEventListener for let's say the click event with a callback. It's going to call the core of JavaScript engine saying
"Hey I have a function that wants to be called everytime there is a click."
The JavaScript engine is going to store a reference to the callback. And then during the JavaScript event loop, everytime there is a click event, it's simply going to call all its references to callback.
So the loop is indeed happening inside the JavaScript event loop (which you have little control over). But your callback is a simple function that subscribed to a specific event and will be called at the right time to react to this event. There is no magic behind it.
In fact, your callback is not really listening for event, it just subscribes itself once to a specific event and then it's done. It might be called in the future, but it's surely not actively listening for it.
As far as I understand, in relation to the common JavaScript literature in 2017 (MDN), we shouldn't say it's a loop, because it's not one of the loops defined in JavaScript like for and while. We can indeed say it's an observer as it observers for each triggering of its associated event.
We don't iterate for each item in a collection, we observe for each triggering of the relevant event; One can say that the "for each" like behavior indicates "loopishness" and I personally find no flaw with that.

Backbone.Radio: what's the advantage of commands and requests over events

It seems like Backbone.Radio provides 2 new abstractions - commands and requests. They're pretty much identical to Backbone.Events, except that they can have only 1 subscriber. Is that it, and if so what advantage do they provide over events?
I plan on using Backbone.Events/Radio with React.js, if that helps.
I have not actually used Backbone.Radio but do make extensive use of Backbone.wreqr https://github.com/marionettejs/backbone.wreqr which provides an almost identical command service.
In my usage the difference between events and commands is:
For events to work the sender and receiver of an event must both exist and have a reference to each other and the receiver must be in a position to deal with the event properly. This can often be problematic in a fully asynchronous browser environment where different parts of your application are running at the same time.
Commands allow you to decouple the sender and receiver. One object, lets say a View A, can simply send command 'update_user_details'.
My second Object View B sets up a command handler for 'update_user_details' which will change the user details on the screen.
But what if View B does not yet exist, or is not yet rendered. In the event listener pattern you would have to make sure View A exists, that it passes a reference to itself to View B and then you attach an event listener in View B.
With commands it is not a problem, View A sends a command, if no-one has set a handler then nothing bad happens, the command just does nothing.
When View B turns up, totally independent of View A, it sets a handler and will respond to all future commands.
Just a final note about intent:
The event pattern can be thought about in this way: I, View A have just done something, anyone that is interested (the event listeners) can do what they like about it, I View A don't care what you do.
In the command pattern: I View A want someone to do something, I don't care who does it, I just want it done right.
Channels. The key difference with Backbone.Radio over plain vanilla Backbone.Events that I have seen is that it allows you to setup channels to which your code can 'tune in' e.g. from the documentation:
var userChannel = Backbone.Radio.channel('user');
This means that logical functions or apps in your code can emit and handle events only on a specific channel - even if you emit events with the same name, if they're on different channels you won't get cross-contamination. This ties in nicely with the principles behind separation of duties in your code.
The other other difference, and IMHO it's subtle, more to do with elegance of coding than any real functionality difference, is that if you're telling something to respond to an event then it's really a Command, and Backbone.Radio allows you to separate these kinds of event into that type. Similar logic applies to the Requests type.
For completeness...
The docs also explain that a Channel is an object that has all three types of messages (Events, Commands and Requests) mixed in. You mix it into an object (I use Marionette so I'm mixing into an instance of Marionette.Object) using Underscore/Lo-Dash's .extend():
_.extend(objectToBeExtended, Backbone.Radio.Requests);
And the same for Commands of course. The syntax for events is different as that's baked into Backbone itself so the second parameter is just Backbone.Events.

What is the difference between different ways of Custom event handling in JavaScript?

I came across the below posts about custom event handling in JavaScript. From these articles, there are two ways (at least) of handling/firing custom events:
Using DOM methods (createEvent, dispatchEvent)
How do I create a custom event class in Javascript?
http://the.unwashedmeme.com/blog/2004/10/04/custom-javascript-events/
Custom code
http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/
http://www.geekdaily.net/2008/04/02/javascript-defining-and-using-custom-events/
But what is the recommended way of handling (firing & subscribing) custom events?
[Edit] The context for this question is not using any libraries like jQuery, YUI,... but just plain JavaScript
[Edit 2] There seems to be a subtle differences, at least with the error handling.
Dean Edwards ( http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/ ) is recommending the former way for custom event handling. Can we say this a difference?
What your describing is the difference between
A custom event based message passing system
manually firing DOM events.
The former is a way to use events for message passing. An example would be creating an EventEmitter
The latter is simply a way to use the browsers build in DOM event system manually. This is basically using the DOM 3 Event API which natively exists in (competent / modern) browsers.
So the question is simply what do you want to do? Fire DOM events or use events for message passing?
Benchmark showing DOM 3 custom events is 98% slower
The DOM appears to have a huge overhead. It does so because it supports event propagation and bubbling. It does because it supports binding events to a DOMElement.
If you do not need any of the features of DOM3 events then use a pub/sub library of choice.
[Edit 2]
That's all about error handling, how you do error handling is upto you. If you know your event emitter is synchronous then that's intended behaviour. Either do your own error handling or use setTimeout to make it asynchronous.
Be wary that if you've made it asynchronous you "lose" the guarantee that the event handlers have done their logic after the emit/trigger/dispatch call returns. This requires a completely different high level design then the assumption that event emitters are synchronous. This is not a choice to make lightly
There are pros and cons to each. Use what suits you.
The most obvious "con" to using the DOM methods is that they're tied to browser-based deployments and involve the DOM in things even if it doesn't really make sense (e.g., the messaging isn't related to DOM objects), whereas a standard Observer-style implementation can be used in any environment, not just web browsers, and with any generic object you like.
The most obvious "con" to doing your own Observer implementation is that you've done your own Observer implementation, rather than reusing something already present (tested, debugged, optimised, etc.) in the environment.
Many libraries already provide a way to deal with events, and I would recommend on just using an existing library. If you use the DOM, you are assuming that the browser provides the necessary support, whereas if you use a custom mechanism, you might be sacrificing speed for the custom implementation. If you rely on an existing library, the library can choose the appropriate tradeoffs.
For example, Closure provides EventTarget which has an interface simliar to that of the DOM mechanism, but which does not depend on the browser to provide native support for it.

Categories

Resources