-
-
Save ItsAsbreuk/6676361 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*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, | |
dataArray = [], | |
e = event._createFacade(dataArray.push.apply(dataArray, data)), | |
i, len, stack; | |
if (subs) { | |
for (i = 0, len = subs.length; i < len; ++i) { | |
// TODO: try/catch? | |
subs[i].fn.call(subs[i].context, e); | |
} | |
} | |
// Execute on() subscribers for each bubble target and their respective targets: | |
if (event.bubbles && !event.stopped) { | |
stack = event.stack || event; | |
eventTarget.bubble(event, args, null, stack); | |
e.prevented = Math.max(e.prevented, stack.prevented); | |
} | |
// 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 ? | |
Y.when(event.preventedFn(e).then(null, function (err) { | |
Y.log("Error in preventedFn: " + (err && (err.message || err)), 'error'); | |
return false; | |
}) | |
: | |
Y.when(event.defaultFn(e).then(function (response) { | |
// 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); | |
} | |
} | |
// Execute after() subscribers for each bubble target and their respective targets: | |
// CODE DOES NOT WORK: on-subscribers are called again! | |
eventTarget.bubble(event, args, null, stack); | |
// 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]); | |
}; |
Luke, thanks!
I got the final code working: created Y.Model.prototype.publishAsync
https://gist.github.com/ItsAsbreuk/6712217
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The bubble method accumulates after subscribers in the event stack's
afterQueue
property. This A) might not work, and B) doesn't support recursive bubbling of the same event.