Skip to content

Instantly share code, notes, and snippets.

@andybryant
Created August 12, 2014 12:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andybryant/b4c8052bd576bd28b1f6 to your computer and use it in GitHub Desktop.
Save andybryant/b4c8052bd576bd28b1f6 to your computer and use it in GitHub Desktop.
Twitter flight promise mixin
define(
['Q', 'jquery'],
function(Q, $) {
'use strict';
function withPromises() {
/*jshint validthis: true */
/**
* Dispatch a message, receiving a promise for the response.
* Possible attributes on args:
* type - event type used to communicate with handler (required)
* element - where to dispatch the event (defaults to component node)
* responseType - event type produced by handler with response (defaults to type + 'Response')
* errorType - event type produced by handler when call fails (defaults to type + 'Error')
* timeout - ms to wait for response before an error is generated. If set to 0, no timeout is used. (defaults to 0, no timeout)
*
* @param args option containing all arguments. The only required argument is type.
*
* @returns a promise
*/
this.call = function(args) {
var deferred = Q.defer(),
correlator = {},
timer;
// add defaults
args = $.extend({
element: this.node,
responseType: args.type + 'Response',
errorType: args.type + 'Error',
timeout: 0
}, args);
this.on(args.element, args.responseType, function(ev, data) {
if (data.correlator === correlator) {
if (timer) {
clearTimeout(timer);
}
deferred.resolve(data.data);
}
});
this.on(args.element, args.errorType, function(ev, data) {
if (data.correlator === correlator) {
if (timer) {
clearTimeout(timer);
}
deferred.reject(new Error(data.data));
}
});
if (args.timeout > 0) {
timer = setTimeout(function() {
deferred.reject('Call timed out');
}, args.timeout);
}
this.trigger(args.element, args.type, {
correlator: correlator,
data: args.data
});
return deferred.promise;
};
/**
* Register a callback for a message generated via the dispatch method.
*
* @param args option containing all arguments. The two required arguments are type and callback
*/
this.registerCall = function(args) {
var component = this, response;
args = $.extend({
element: this.node,
responseType: args.type + 'Response',
errorType: args.type + 'Error'
}, args);
args.callback = args.callback.bind(this);
this.on(args.element, args.type, function(ev, data) {
var correlator = data.correlator, origData = data.data;
try {
response = args.callback(origData);
component.trigger(args.element, args.responseType,
{ correlator: correlator, data: response });
} catch (err) {
component.trigger(args.element, args.errorType,
{ correlator: correlator, data: err });
}
});
};
}
// return the mixin function
return withPromises;
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment