私はこのようなものを持っています。それは、値や文字列を返してくれるスクリプトへの単純な呼び出しです。
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
しかし、このようなものを呼び出すと
var output = testAjax(svar); // output will be undefined...
のように呼び出した場合、どのようにして値を返せばよいのでしょうか? 以下のコードもうまくいかないようです。
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
}
});
return data;
}
注:この回答は2010年2月に書かれたものです。
下部にある2015年、2016年、2017年の更新情報をご覧ください。
非同期の関数からは何も返すことができません'。返すことができるのは、promiseです。jQueryで約束がどのように機能するかは、これらの質問に対する回答で説明しました。
function testAjax() {
$.ajax({
url: "getvalue.php",
success: function(data) {
return data;
}
});
}
の代わりに、 testAjax関数を次のように書くことができます。
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
そして、次のようにしてプロミスを取得します。
var promise = testAjax();
しかし、最終的に AJAX 呼び出しによって返されたデータを 使用 したいときには、次のようにしなければなりません。
promise.success(function (data) {
alert(data);
});
現在(2015年3月時点)、jQuery Promisesは[Promises/A+仕様]( http://promises-aplus.github.io/promises-spec/)と互換性がないため、他の[Promises/A+準拠の実装](https://github.com/promises-aplus/promises-spec/blob/master/implementations.md)とはあまりうまく連携できない可能性があります。 しかし、次期バージョン3.xのjQuery Promisesは**Promises/A+仕様との互換性を持つ予定です(指摘してくれたBenjamin Gruenbaumに感謝します)。現在(2015年5月時点)のjQueryの安定版は1.xと2.xです。
上(2011年3月)で説明したのは、jQuery Deferred Objectsを使って、同期コードでは値を返すことで実現するようなことを非同期で行う方法です。 しかし、同期関数の呼び出しには2つのことができます。値を返せる場合は値を返し、返せない場合は例外を投げるのです。Promises/A+は、同期コードでの例外処理と同じくらい強力な方法で、これらのユースケースの両方に対応しています。jQuery版では、値を返すことに相当する処理はうまくいっているが、複雑な例外処理に相当する処理はやや問題がある。 特に、同期コードにおける例外処理の要点は、単にメッセージを出して諦めるのではなく、問題を解決して実行を継続したり、同じまたは異なる例外を再スローしてプログラムの他の部分で処理させたりすることにある。同期コードでは、コールスタックがあります。Promises/A+仕様で要求されているように、プロミスの中で高度な例外処理を行うことで、複雑なユースケースでもエラーや例外を意味のある形で処理するコードを書くことができます。 jQueryと他の実装の違いや、jQueryのプロミスをPromises/A+準拠に変換する方法については、Q library wikiのKris Kowal氏らによるComing from jQueryや、HTML5 RocksのJake Archibald氏によるPromises arrive in JavaScriptを参照してください。
上の例で出てきた関数です。
function testAjax() {
return $.ajax({
url: "getvalue.php"
});
}
は、jQueryのDeferred ObjectであるjqXHRオブジェクトを返しています。 これを本当のpromiseを返すようにするには、Q wikiのメソッド](https://github.com/kriskowal/q/wiki/Coming-from-jQuery#converting-jquery-promises-to-q)を使って、次のように変更します。
function testAjax() {
return Q($.ajax({
url: "getvalue.php"
}));
}
または、HTML5 Rocks articleのメソッドを使用します。
function testAjax() {
return Promise.resolve($.ajax({
url: "getvalue.php"
}));
}
この Promise.resolve($.ajax(...))
は、promise` モジュールのドキュメントで説明されているものでもあり、ES6 Promise.resolve()
でも動作するはずです。
現在、ES6のプロミスを使用するには、Jake Archibald氏によるes6-promise module's polyfill()
があります。
ポリフィルを使わずにES6のPromisesを使える場所については、こちらをご覧ください。Can I use: Promisesをご覧ください。
より詳しい情報はこちらをご覧ください。
jQueryの将来のバージョン(3.xから - 2015年5月現在の安定版は1.xと2.x)は、Promises/A+仕様との互換性があります(コメントで指摘してくれたBenjamin Gruenbaumに感謝します)。"すでに決定している2つの変更点は、Deferred実装のPromise/A+互換性です[...]" (jQuery 3.0 and the future of Web development)。詳しくはこちらをご覧ください。Dave Methvin氏のjQuery 3.0: The Next GenerationsとPaul Krill氏のjQuery 3.0: More interoperability, less Internet Explorerを参照。
ECMA-262, 6th Edition, Section 14.2](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions)には、[arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions)という新しい構文があり、上記の例をさらにシンプルにするために利用できるかもしれません。 jQuery APIを使用すると、代わりに
promise.success(function (data) {
alert(data);
});
の代わりに、次のように書くことができます。
promise.success(data => alert(data));
また、Promises/A+ APIを使用した場合は
promise.then(data => alert(data));
拒絶反応ハンドラは、常に
promise.then(data => alert(data), error => alert(error));
のどちらかを使用してください。
promise.then(data => alert(data)).catch(error => alert(error));
拒否ハンドラを常に約束と一緒に使うべき理由については、この回答を参照してください。
alert
を呼び出しているだけなので、単に promise.then(alert)
を使うこともできますが、矢印構文はより一般的で、以下のように書くことができます。promise.then(data => alert("x is " + data.x));
すべてのブラウザがこの構文をサポートしているわけではありませんが、コードがどのブラウザで実行されるかがはっきりしている場合があります。例えば、Chrome extension、Firefox Add-on、Electron、NW.js、AppJSを使ったデスクトップアプリケーションを書く場合などです(詳細はこの回答を参照してください)。 なお、矢印関数のサポートについては
await
キーワードを使って、このコードの代わりにfunctionReturningPromise()
.then(data => console.log('Data:', data))
.catch(error => console.log('Error:', error));
と書くことができます。
try {
let data = await functionReturningPromise();
console.log('Data:', data);
} catch (error) {
console.log('Error:', error);
}
このキーワードは、async
キーワードで作成された関数の中でのみ使用できます。詳細は以下を参照してください。
や
await` をネイティブでサポートしていない場所では、Babel を使うことができます。co
や Bluebird coroutines のようなジェネレータベースのアプローチがあります。プロミスに関する他の質問についてはこちらをご覧ください。
関数からデータを返すには、非同期呼び出しではなく同期呼び出しを行うしかありませんが、そうするとレスポンスを待っている間にブラウザがフリーズしてしまいます'。
結果を処理するコールバック関数を渡すことができます。
function testAjax(handleData) {
$.ajax({
url:"getvalue.php",
success:function(data) {
handleData(data);
}
});
}
このように呼び出します。
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.
jquery docsの例を参照してください。 http://api.jquery.com/jQuery.ajax/ (ページの約2/3)
以下のコードを探しているかもしれません。
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});
同じページの...下の方にあります。