(UPDATE:
Please note that currently jQuery Promises are not compatible with the Promises/A+ specification - more info in this answer.)
In your function where you create the AJAX request you can also create a deferred object and return a promise to the caller after binding its resolve and reject functions to the appropriate callbacks of the $.ajax request with some custom data verification, like this:
function makerequest() {
var deferred = $.Deferred();
var promise = deferred.promise();
var jqxhr = $.ajax({
// ...
});
jqxhr.success(function(data, status, xhr) {
if (!data || !data.success) {
deferred.reject(jqxhr, 'error');
} else {
deferred.resolve(data, status, xhr);
}
});
jqxhr.error(function(jqXHR, status, error) {
deferred.reject(jqXHR, status, error);
});
return promise;
}
Now anyone will be able to use it like any promise like this to your function:
var request = makerequest();
request.done(successCallback);
request.fail(errorCallback);
Or even just:
makerequest().then(successCallback, errorCallback);
If you also add this:
promise.success = promise.done;
promise.error = promise.fail;
then your caller will have (maybe more familiar) interface of .success() and .error() like with pure $.ajax() calls:
var request = makerequest();
request.success(successCallback);
request.error(errorCallback);
(The implementation of .complete() is left as an exercise for the reader.)
See this demos:
Here's another example pulled directly from a working project:
function ajax(url, data) {
var self = this;
var deferred = $.Deferred();
var promise = deferred.promise();
var jqxhr = $.ajax({
url: url,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: 'json',
type: 'POST'
}).done(function (msg, status, xhr) {
if (!msg || msg.Error) {
self.doError(msg.Error);
deferred.reject(jqxhr, 'error');
} else {
deferred.resolve(msg, status, xhr);
}
});
return promise;
}