-
-
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