Skip to content

Instantly share code, notes, and snippets.

@espretto
Last active August 29, 2015 14:06
Show Gist options
  • Save espretto/0e686b313879514c258b to your computer and use it in GitHub Desktop.
Save espretto/0e686b313879514c258b to your computer and use it in GitHub Desktop.
JavaScript: promisified jQuery.ajax
// promisify $.ajax with Q
// =======================
var ns = {};
ns.ajax = (function($, Q){
var defaults = {
type: 'GET',
async: true,
// cache: false,
crossDomain: true,
contentType: 'application/json; charset=UTF-8'
},
callbacks = 'always,complete,done,error,fail,pipe,success'.split(','),
length = callbacks.length;
// enforce then-api
// ----------------
function hasRegisteredCallback(options){
for(var i = length; i--;) if(callbacks[i] in options) return true;
return false;
}
return function(options){
if(hasRegisteredCallback(options)){
throw new Error('use then-api instead of callbacks');
}
var deferred = Q.defer(),
upload;
// apply settings
// --------------
options = $.extend({}, defaults, options);
// register progress handlers
// --------------------------
if(!('xhr' in options)){
options.xhr = function(){
var xhr = $.ajaxSettings.xhr(),
$xhr = $(xhr);
upload = xhr.upload;
$xhr.on('readystatechange', function(evt){
deferred.notify({evt: evt, msg: 'readystate', xhr: xhr});
});
if(upload){
$xhr.on('progress', function(evt){
deferred.notify({evt: evt, msg: 'upload', xhr: xhr});
});
}
return xhr;
};
}
// kick off
// --------
$.ajax(options)
.done(function(data, msg, xhr) {
deferred.resolve({data: data, msg: msg, xhr: xhr});
})
.fail(function(xhr, msg, err) {
deferred.reject({error: err, msg: msg, xhr: xhr});
})
.always(function(xhr){
if(upload) $(upload).off('progress');
$(xhr).off('readystatechange');
});
return deferred.promise;
};
}(jQuery, Q));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment