Ich erstelle ein Ajax-Dienstprogramm für die Schnittstelle zu meinen Servermethoden. Ich möchte jQuery 1.5+ verzögerte Methoden aus dem Objekt nutzen, das vom Aufruf von jQuery.ajax() zurückgegeben wird. Die Situation ist folgende.
-
Die serverseitige Methode gibt immer ein JSON-Objekt zurück:
{ success: true|false, data: ... }
-
Das clientseitige Dienstprogramm initiiert den Ajax-Aufruf wie folgt
var jqxhr = $.ajax({ ... });
-
Und die Problemzone:
jqxhr.success(function(data, textStatus, xhr) {
if(!data || !data.success) {
???? // abort processing, trigger error
}
});
return jqxhr; // return to caller so he can attach his own handlers
Die Frage ist also, wie man den Aufruf aller an den Aufrufer angehängten Erfolgs-Callbacks abbricht und seinen Error-Handler an der genannten Stelle auslöst ????
?
Die Dokumentation besagt, dass die Listen der verzögerten Funktionsaufrufe FIFO sind, also ist mein Erfolgshandler definitiv der erste.
(AKTUALISIEREN:
Bitte beachten Sie, dass derzeit jQuery Promises nicht mit dem kompatibel sind Versprechungen/A+ Spezifikation – Weitere Informationen in dieser Antwort.)
In Ihrer Funktion, in der Sie die AJAX-Anforderung erstellen, können Sie auch ein zurückgestelltes Objekt erstellen und dem Aufrufer ein Versprechen zurückgeben, nachdem Sie seine Auflösungs- und Ablehnungsfunktionen mit einer benutzerdefinierten Datenüberprüfung an die entsprechenden Rückrufe der $.ajax-Anforderung gebunden haben, wie folgt:
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;
}
Jetzt kann jeder es wie jedes Versprechen wie dieses für Ihre Funktion verwenden:
var request = makerequest();
request.done(successCallback);
request.fail(errorCallback);
Oder auch nur:
makerequest().then(successCallback, errorCallback);
Wenn Sie dies auch hinzufügen:
promise.success = promise.done;
promise.error = promise.fail;
dann hat Ihr Aufrufer eine (vielleicht vertrautere) Schnittstelle von .success() und .error() wie bei reinen $.ajax()-Aufrufen:
var request = makerequest();
request.success(successCallback);
request.error(errorCallback);
(Die Implementierung von .complete() bleibt dem Leser als Übung überlassen.)
Sehen Sie sich diese Demos an:
Hier ist ein weiteres Beispiel, das direkt aus einem Arbeitsprojekt gezogen wurde:
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;
}
.