My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Saturday, February 01, 2014

eddy.js goes promisish

This is a quick one about the tiny library I am using the most for personal projects: eddy.js

Promised Events

eddy makes the creation of event driven logic and application the easiest possible you can imagine.
var obj = {};

// at any time, in any place
obj.on('event', doSomething);
The unobtrusive, memory safe and lazily attached EventTarget logic you can even overwrite whenever you like to anywhere in your code, cannot solve tasks in a way ES6 Promises would.

... but what if I told you ...

... that jQuery nailed it in a similar way since ever?

.when(something, happened)

A very basic example of this new method is a classic document.ready approach indeed:
// even if lazily loaded!
document.when('ready', function(e){
  console.log('we are ready to go');
});

// later, even loaded asynchronously
// with or without AMD
document.when('ready', initLibrary);
Even if manually dispatched, handlers that has been fired once will not fire again unless re-attached but even doing so, these won't be fired twice if previously attached.
The best of both worlds, where listeners are stored by reference once, without the possibility to be fired more than once.
.once() is indeed the closest example to .when() except once adds a new listener, if not previously added, regardless the operation happened already in the past.
With this .when() method we are sure that the very first time the event happens, every other listener could benefit from that result.

result but no implicit reject

The "fulfill" part of this concept is provided by the way we dispatch the event either with .trigger('DOM-like', details) or .emit('node-like', null, value).
Any listener will receive the event or value passed the very first time the fulfill occurs but there is no way to understand a rejected value if not analyzing arguments.
A reject can be easily simulated indeed via .trigger('DOM-like', new Error('problem')) or .emit('node-like', new Error('problem'), null) so that any listener could handle failures.

improved .boundTo()

Another small change to library has been enriching Object#boundTo() signature so that it is possible to assign if not present once and at runtime.
I've found myself repeating this kind of pattern over and over:
obj.on('evt',
  obj.someMethod || (
  obj.someMethod = function(e) {
    // everything I need
  }
));
With the current improvement to boundTo, which I found more appropriate than creating another method for all objects, we can simply do this:
obj.on(
  'evt',
  obj.boundTo('someMethod', function(e) {
    // everything I need
  })
);
Above code will assign the second function argument only once and only if someMethod has not been assigned already. If a bound version is not required, then we could go in a less elegant way and either use the initial approach I've showed or simply addressing the property after:
obj.on(
  'evt',
  // not the bound version
  obj.boundTo('someMethod', function(e) {
    // everything I need
  }).someMethod // there it is!
);
The method does not create indeed a bound copy of the function as property, it rather addresses it once per property.

boundTo(Caveat)

It's very simple to create a foot-gun. If we address two different functions with the same property name only the first one will be used and never the last. In this case is highly recommended to delete obj.someMethod before using again boundTo ease.

Summary

eddy.js is becoming addictive and I am holding back myself every time I'd like to add some new cool thing trying to avoid mistakes old libraries did and keeping it simple and unobtrusive but I strongly suggest you to give it a shot.
Enjoy!

No comments: