Ich habe etwas wie dieses, wo es einen einfachen Aufruf zu einem Skript, das mir einen Wert, eine Zeichenfolge zurückgibt ist.
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
aber wenn ich etwas wie dieses aufrufe
var output = testAjax(svar); // output will be undefined...
wie kann ich dann den Wert zurückgeben? der folgende Code scheint auch nicht zu funktionieren...
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
}
});
return data;
}
Anmerkung: Diese Antwort wurde im Februar 2010 verfasst.Aktualisierungen aus den Jahren 2015, 2016 und 2017 finden Sie am Ende. Sie können aus einer asynchronen Funktion nichts zurückgeben. Was Sie zurückgeben können, ist ein Versprechen. Wie Versprechen in jQuery funktionieren, habe ich in meinen Antworten auf diese Fragen erklärt:
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
können Sie Ihre testAjax-Funktion wie folgt schreiben:
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
Dann können Sie Ihr Versprechen wie folgt erhalten:
var promise = testAjax();
Sie können Ihr Versprechen speichern, Sie können es weitergeben, Sie können es als Argument in Funktionsaufrufen verwenden und Sie können es von Funktionen zurückgeben, aber wenn Sie schließlich Ihre Daten, die von dem AJAX-Aufruf zurückgegeben werden, verwenden wollen, müssen Sie es so machen:
promise.success(function (data) {
alert(data);
});
Derzeit (Stand März 2015) sind jQuery Promises nicht mit der Promises/A+ Spezifikation kompatibel, was bedeutet, dass sie möglicherweise nicht sehr gut mit anderen Promises/A+ konformen Implementierungen zusammenarbeiten. Allerdings wird jQuery Promises in der kommenden Version 3.x mit der Promises/A+-Spezifikation kompatibel sein (Dank an Benjamin Gruenbaum für den Hinweis darauf). Derzeit (Stand: Mai 2015) sind die stabilen Versionen von jQuery 1.x und 2.x.
Was ich oben (im März 2011) erklärt habe, ist eine Möglichkeit, [jQuery Deferred Objects] (https://api.jquery.com/category/deferred-object/) zu verwenden, um etwas asynchron zu tun, das in synchronem Code durch die Rückgabe eines Wertes erreicht würde. Aber ein synchroner Funktionsaufruf kann zwei Dinge tun - er kann entweder einen Wert zurückgeben (wenn er kann) oder eine Ausnahme auslösen (wenn er keinen Wert zurückgeben kann). Promises/A+ adressiert beide Anwendungsfälle auf eine Art und Weise, die ziemlich genau so mächtig ist wie die Ausnahmebehandlung in synchronem Code. Die jQuery-Version behandelt das Äquivalent der Rückgabe eines Wertes sehr gut, aber das Äquivalent der komplexen Ausnahmebehandlung ist etwas problematisch. Insbesondere geht es bei der Behandlung von Ausnahmen in synchronem Code nicht nur darum, mit einer netten Nachricht aufzugeben, sondern zu versuchen, das Problem zu beheben und die Ausführung fortzusetzen oder möglicherweise die gleiche oder eine andere Ausnahme für andere Teile des Programms erneut auszulösen. In synchronem Code haben Sie einen Aufrufstapel. Bei asynchronen Aufrufen ist das nicht der Fall, und eine fortschrittliche Ausnahmebehandlung innerhalb Ihrer Promises, wie sie in der Promises/A+-Spezifikation gefordert wird, kann Ihnen wirklich dabei helfen, Code zu schreiben, der Fehler und Ausnahmen auf sinnvolle Weise behandelt, selbst bei komplexen Anwendungsfällen. Zu den Unterschieden zwischen jQuery und anderen Implementierungen und zur Konvertierung von jQuery-Promises in Promises/A+-konforme Promises, siehe Coming from jQuery von Kris Kowal et al. auf dem Q library wiki und Promises arrive in JavaScript von Jake Archibald auf HTML5 Rocks.
Die Funktion aus meinem obigen Beispiel:
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
gibt ein jqXHR-Objekt zurück, das ein jQuery Deferred Object ist. Damit es ein echtes Versprechen zurückgibt, können Sie es ändern in - mit der Methode aus dem Q-Wiki:
function testAjax() {
return Q($.ajax({
url: "getvalue.php"
}));
}
oder mit der Methode aus dem HTML5 Rocks Artikel:
function testAjax() {
return Promise.resolve($.ajax({
url: "getvalue.php"
}));
}
Dieses Promise.resolve($.ajax(...))
ist auch das, was in der promise
Modul Dokumentation erklärt wird und es sollte mit ES6 Promise.resolve()
funktionieren.
Um die ES6 Promises heute zu verwenden, können Sie es6-promise module's polyfill()
von Jake Archibald verwenden.
Um zu sehen, wo Sie die ES6 Promises ohne das Polyfill verwenden können, siehe: Kann ich verwenden: Promises.
Für weitere Informationen siehe:
Zukünftige Versionen von jQuery (ab 3.x - aktuelle stabile Versionen ab Mai 2015 sind 1.x und 2.x) werden mit der Promises/A+ Spezifikation kompatibel sein (Dank an Benjamin Gruenbaum für den Hinweis in den Kommentaren). "Zwei Änderungen, die wir bereits beschlossen haben, sind Promise/A+ Kompatibilität für unsere Deferred Implementierung [...]" (jQuery 3.0 und die Zukunft der Webentwicklung). Für weitere Informationen siehe: jQuery 3.0: The Next Generations von Dave Methvin und jQuery 3.0: Mehr Interoperabilität, weniger Internet Explorer von Paul Krill.
Es gibt eine neue Syntax in ECMA-262, 6th Edition, Section 14.2 namens arrow functions, die zur weiteren Vereinfachung der obigen Beispiele verwendet werden kann. Bei der Verwendung der jQuery-API wird anstelle von:
promise.success(function (data) {
alert(data);
});
können Sie schreiben:
promise.success(data => alert(data));
oder unter Verwendung der Promises/A+-API:
promise.then(data => alert(data));
Denken Sie daran, immer Ablehnungshandler zu verwenden, entweder mit:
promise.then(data => alert(data), error => alert(error));
oder mit:
promise.then(data => alert(data)).catch(error => alert(error));
In dieser Antwort erfahren Sie, warum Sie Ablehnungshandler immer mit Versprechen verwenden sollten:
promise.then(alert)
verwenden, weil man nur alert
mit den gleichen Argumenten wie den Callback aufruft, aber die Pfeil-Syntax ist allgemeiner und erlaubt es, Dinge wie:promise.then(data => alert("x is " + data.x));
Noch unterstützt nicht jeder Browser diese Syntax, aber es gibt bestimmte Fälle, in denen Sie sicher sind, auf welchem Browser Ihr Code laufen wird - z.B. wenn Sie eine Chrome-Erweiterung, ein Firefox-Add-on oder eine Desktop-Anwendung mit Electron, NW.js oder AppJS schreiben (siehe diese Antwort für Details). Für die Unterstützung von Pfeilfunktionen, siehe:
await
-Schlüsselwort, das anstelle dieses Codes:functionReturningPromise()
.then(data => console.log('Data:', data))
.catch(error => console.log('Error:', error));
schreiben lässt:
try {
let data = await functionReturningPromise();
console.log('Data:', data);
} catch (error) {
console.log('Error:', error);
}
Sie können es nur innerhalb einer Funktion verwenden, die mit dem Schlüsselwort "async" erstellt wurde. Für weitere Informationen, siehe:
async
und await
gibt, können Sie Babel verwenden:co
oder Bluebird Coroutines:Einige andere Fragen zu Promises für mehr Details:
Die einzige Möglichkeit, die Daten aus der Funktion zurückzugeben, bestünde darin, einen synchronen Aufruf anstelle eines asynchronen Aufrufs zu machen, aber das würde den Browser einfrieren, während er auf die Antwort wartet.
Sie können eine Callback-Funktion übergeben, die das Ergebnis verarbeitet:
function testAjax(handleData) {
$.ajax({
url:"getvalue.php",
success:function(data) {
handleData(data);
}
});
}
Rufen Sie sie wie folgt auf:
testAjax(function(output){
// here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
Siehe jquery docs Beispiel: http://api.jquery.com/jQuery.ajax/ (etwa 2/3 der Seite)
Vielleicht suchen Sie den folgenden Code:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});
Dieselbe Seite...weiter unten.