jQueryを使用しています。ajaxコールの成功後にデータを返す
私はこのようなものを持っています。それは、値や文字列を返してくれるスクリプトへの単純な呼び出しです。
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;
}
444
3
注:この回答は2010年2月に書かれたものです。
下部にある2015年、2016年、2017年の更新情報をご覧ください。 非同期の関数からは何も返すことができません'。返すことができるのは、promiseです。jQueryで約束がどのように機能するかは、これらの質問に対する回答で説明しました。
の代わりに、 testAjax関数を次のように書くことができます。
そして、次のようにしてプロミスを取得します。
しかし、最終的に AJAX 呼び出しによって返されたデータを 使用 したいときには、次のようにしなければなりません。
(簡略化された構文については、以下のアップデートを参照してください。) もしあなたのデータがこの時点で利用可能であれば、この関数は直ちに呼び出されます。もしそうでなければ、データが利用可能になり次第、この関数が呼び出されます。 このような処理を行うポイントは、$.ajaxが非同期であるため、呼び出した直後にはデータが利用できないということです。プロミスは、関数を抽象化して言うことができます。私はまだデータを持っていないので、あなたにデータを返すことができません。私はブロックしてあなたを待たせたくないので、代わりにここにpromiseを用意しました。 この[DEMO](http://jsfiddle.net/jW68r/)をご覧ください。 アップデイト(2015年
現在(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を参照してください。
本当のプロミスを返すには
上の例で出てきた関数です。
は、jQueryのDeferred ObjectであるjqXHRオブジェクトを返しています。 これを本当のpromiseを返すようにするには、Q wikiのメソッド](https://github.com/kriskowal/q/wiki/Coming-from-jQuery#converting-jquery-promises-to-q)を使って、次のように変更します。
または、HTML5 Rocks articleのメソッドを使用します。
この
Promise.resolve($.ajax(...))
は、promise` モジュールのドキュメントで説明されているものでもあり、ES6Promise.resolve()
でも動作するはずです。 現在、ES6のプロミスを使用するには、Jake Archibald氏によるes6-promise module'spolyfill()
があります。 ポリフィルを使わずにES6のPromisesを使える場所については、こちらをご覧ください。Can I use: Promisesをご覧ください。 より詳しい情報はこちらをご覧ください。今後のjQueryについて
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を参照。
興味深い講演
[JavaScript Promises](https://youtu.be/oa2clhsYIDY) by David M. Lee (Nodevember 2014) アップデイト(2016年
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を使用すると、代わりに
の代わりに、次のように書くことができます。
また、Promises/A+ APIを使用した場合は
拒絶反応ハンドラは、常に
のどちらかを使用してください。
拒否ハンドラを常に約束と一緒に使うべき理由については、この回答を参照してください。
alert
を呼び出しているだけなので、単にpromise.then(alert)
を使うこともできますが、矢印構文はより一般的で、以下のように書くことができます。すべてのブラウザがこの構文をサポートしているわけではありませんが、コードがどのブラウザで実行されるかがはっきりしている場合があります。例えば、Chrome extension、Firefox Add-on、Electron、NW.js、AppJSを使ったデスクトップアプリケーションを書く場合などです(詳細はこの回答を参照してください)。 なお、矢印関数のサポートについては
await
キーワードを使って、このコードの代わりにと書くことができます。
このキーワードは、
async
キーワードで作成された関数の中でのみ使用できます。詳細は以下を参照してください。や
await` をネイティブでサポートしていない場所では、Babel を使うことができます。co
や Bluebird coroutines のようなジェネレータベースのアプローチがあります。http://bluebirdjs.com/docs/api/promise.coroutine.html その他の情報
プロミスに関する他の質問についてはこちらをご覧ください。
関数からデータを返すには、非同期呼び出しではなく同期呼び出しを行うしかありませんが、そうするとレスポンスを待っている間にブラウザがフリーズしてしまいます'。
結果を処理するコールバック関数を渡すことができます。
このように呼び出します。
jquery docsの例を参照してください。 http://api.jquery.com/jQuery.ajax/ (ページの約2/3)
以下のコードを探しているかもしれません。
同じページの...下の方にあります。