Is there any way to implement event-driven programming in JavaScript, without involving any DOM element? Such as creating an event-handler which executed every time an array get sorted.
3 Answers
Sure! The keyword you're looking for is "pubsub". Here are some well-known implementations:
But you could also do it yourself, like so:
window.pubsub = (function () {
var eventToListeners = {};
return {
sub: function (event, callback) {
if (!eventToListeners.hasOwnProperty(event)) {
eventToListeners[event] = [];
}
eventToListeners[event].push(callback);
},
pub: function (event, args) {
if (eventToListeners.hasOwnProperty(event)) {
for (var i = 0; i < eventToListeners[event].length; ++i) {
try {
eventToListeners[event][i].call(null, args);
} catch (e) {
if (console && console.error) {
console.error(e);
}
}
}
}
}
};
}());
// Sample usage:
pubsub.sub("arraySorted", function () {
console.log("array was sorted");
});
var myArray = [2, 3, 1];
myArray.sort();
pubsub.pub("arraySorted");
5 Comments
Magnar
Remember to wrap the call in a try-catch block to ensure all subscribers are called even if one fails.
Domenic
@Magnar: Thanks for the suggestion; implemented!
Dwi Ash
Whoa!! thank you so much!! i never knew about this Pub/Sub thingy before. it really helped me out! thx :)
Șerban Ghiță
@Domenic thanks for the answer, I think this is one of the most clear and simple answers related to Pub/Sub that I've found so far.
Thomas Ludewig
Great ! i just want to point out that "pubSub" is just a random function name. Any other would work as well. In my Opinion something like "customEvent" would match it better :)
In newish browsers, we've added the ability to construct an EventTarget directly:
const et = new EventTarget();
et.addEventListener("arraySorted", () => {
console.log("array was sorted");
});
const myArray = [2, 3, 1];
myArray.sort();
et.dispatchEvent(new Event("arraySorted"));
See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget for more examples as well as a browser compatibility table. As of the time of this writing it only works in Chrome (64+) and Firefox (59+), but over time support will expand to include Safari and Edge.