-
-
Save lsmith/6664382 to your computer and use it in GitHub Desktop.
/*global SM:true*/ | |
'use strict'; | |
// Publish a very special, promise-compatible event that supports the default | |
// function behavior to chain on internally created promises before executing | |
// the after() subs. on() subs can still e.preventDefault(), which will | |
// reject the promise and thus skip the default behavior and after() subs. | |
var asyncEvent = eventTarget.publish('foo'); | |
asyncEvent._firing = new Y.Promise(function (resolve) { resolve(); }); | |
asyncEvent.fire = function (data) { | |
var event = this, | |
args = Y.Array(arguments, 0, true); | |
event._firing = event._firing.then(function () { | |
event.details = args; | |
// Execute on() subscribers | |
var subs = event._subscribers, | |
e = event._createFacade(data), | |
i, len; | |
if (subs) { | |
for (i = 0, len = subs.length; i < len; ++i) { | |
// TODO: try/catch? | |
subs[i].fn.call(subs[i].context, e); | |
} | |
} | |
// Resolve the _firing promise with either false if it was prevented, or with a promise for | |
// the result of the defaultFn followed by the execution of the after subs. | |
return e.prevented ? | |
false : // Doesn't support preventedFn, but could | |
Y.when(event.defaultFn.call(event.context || event, e)).then(function (e) { | |
// Execute after() subscribers | |
subs = event._afters; | |
if (subs) { | |
for (i = 0, len = subs.length; i < len; ++i) { | |
subs[i].fn.call(subs[i].context, e); | |
} | |
} | |
// Catch errors/preventions and reset the promise state to fulfilled for | |
// the next call to fire(); | |
}).then(null, function (err) { | |
Y.log("Error in defaultFn or after subscriber: " + (err && (err.message || err)), 'error'); | |
return false; | |
}); | |
}); | |
}; | |
asyncEvent._fire = function (args) { | |
return this.fire(args[0]); | |
}; |
e = event._createFacade(data),
needs to be changed into:
args = [],
e = event._createFacade(args.push.apply(args, data)),
Hmmm, for some reason, the eventobject gets lost when calling event._createFacade. It is on the data-object thought.
Gotta search out why.
Luke, could you help me out?
I need to pass an eventobject as well. Without altering the code (as described above), the code will hang at https://github.com/yui/yui3/blob/master/src/event-custom/js/event-facade.js#l401
But with the adjustements, there is no event-data, because this.details is undefined at https://github.com/yui/yui3/blob/master/src/event-custom/js/event-facade.js#l378
- Marco
Luke, need some more help:
The event cannot be targetted to another EventTarget instance.
var someTarget = new Y.EventTarget();
myobject.addTarget(myTarget);
myTarget.on('*:foo', function() {
... <-- nothing happens
});
myobject.fire('foo');
Luke, thanks!
I got the final code working: created Y.Model.prototype.publishAsync
https://gist.github.com/ItsAsbreuk/6712217
One small bugfix:
line 40-42 should be arrounded by:
if (subs) {
}
Wow, Luke, this is great code!
You really should bring this in the core of CustomEvent in order to make promise-defFn's working by default.
Regards,
Marco