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; 
}

注:この回答は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);
});

(簡略化された構文については、以下のアップデートを参照してください。) もしあなたのデータがこの時点で利用可能であれば、この関数は直ちに呼び出されます。もしそうでなければ、データが利用可能になり次第、この関数が呼び出されます。 このような処理を行うポイントは、$.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を参照してください。

本当のプロミスを返すには

上の例で出てきた関数です。

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をご覧ください。 より詳しい情報はこちらをご覧ください。

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));

拒否ハンドラを常に約束と一緒に使うべき理由については、この回答を参照してください。

promise.then(data => alert("x is " + data.x));

すべてのブラウザがこの構文をサポートしているわけではありませんが、コードがどのブラウザで実行されるかがはっきりしている場合があります。例えば、Chrome extensionFirefox 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 キーワードで作成された関数の中でのみ使用できます。詳細は以下を参照してください。

解説 (9)
ソリューション

関数からデータを返すには、非同期呼び出しではなく同期呼び出しを行うしかありませんが、そうするとレスポンスを待っている間にブラウザがフリーズしてしまいます'。

結果を処理するコールバック関数を渡すことができます。

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.
解説 (7)

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.');
   }
});

同じページの...下の方にあります。

解説 (0)