web-dev-qa-db-ja.com

jQueryを使用して関数で$ .getデータを返す

JQueryコードを含む関数を呼び出そうとしています。この関数がjQueryステートメントの結果を返すようにします。それは機能していません、そして私は理由を理解しようとしています。

_function showGetResult (name) {
    var scriptURL = "somefile.php?name=" + name;
    return $.get(scriptURL, {}, function(data) { return data; });
}

alert (showGetResult("John"));
_

アラートには「_[object XMLHttpRequest]_」と表示されます。ただし、関数の外部でjQueryステートメントを単独で実行すると、正常に動作します-> $.get(scriptURL, {}, function(data) { alert(data); })

_$.get_データを返す関数内にコードを配置することで、このコードを再利用できるようにしたいと思います。私はここでどんな根本的な間違いを犯していますか?

33
Kai

いくつかの異なる間違いがあります。まず、$。getはコールバック関数の戻り値を返しません。 XHRオブジェクトを返します。次に、get関数は同期ではなく、非同期であるため、showGetResultはgetが完了する前に戻る可能性があります。第三に、コールバック内部から外部スコープに何かを返すことはできません。ただし、外部スコープで変数をバインドし、コールバックで設定できます。

必要な機能を取得するには、$。ajaxを使用し、asyncオプションをfalseに設定する必要があります。次に、外部スコープで変数を定義し、ajaxコールバックで変数を割り当てて、この変数を関数から返します。

function showGetResult( name )
{
     var result = null;
     var scriptUrl = "somefile.php?name=" + name;
     $.ajax({
        url: scriptUrl,
        type: 'get',
        dataType: 'html',
        async: false,
        success: function(data) {
            result = data;
        } 
     });
     return result;
}

ただし、非同期呼び出しから同期呼び出しに変更するのではなく、コールバック関数自体で必要なことを行う方法を見つけ出す方がおそらく役立つでしょう。

94
tvanfosson

あなたが犯している根本的な間違いは、AJAXの呼び出しが非同期で行われるため、戻るまでに結果がまだ準備できていないことです。

$(function() {
    showGetResult('John');
});

function showGetResult (name) {
    $.get('somefile.php', { 
        // Pass the name parameter in the data hash so that it gets properly
        // url encoded instead of concatenating it to the url.
        name: name 
    }, function(data) { 
        alert(data); 
    });
}
9
Darin Dimitrov

同期リクエストが必要なようです: jQueryに非同期Ajaxリクエストではなく同期Ajaxリクエストを実行させるにはどうすればよいですか?

または、コールバックを関数に渡すこともできます。

function showGetResult (name, callback) {
  var scriptURL = "somefile.php?name=" + name;
  return $.get(scriptURL, {}, callback);
}

showGetResult("John", function(data){ alert(data); });
6
queen3

基本的な間違いは、AJAXの「非同期」部分です。サーバーが応答を返送するのにどれくらいの時間がかかるかわからないため、AJAXメソッドは「ブロック」することはありません。つまり、サーバーを呼び出して座っているだけではありません代わりに、別の処理に進みますが、結果が戻ったときに起動する「コールバック」と呼ばれるメソッドを設定します。このメソッドは、データ(たとえば、ページに挿入する)。

2
Jacob Mattison

これは間違った方法です。 function(data)はコールバック関数なので、return $ .getが実行されるたびに、コールバック関数が呼び出されなかった可能性があります。

投稿データは、function(data)メソッドからget関数を呼び出す方が良いでしょう。

1
jatanp

効率的な方法は、jQueryのDeferredメソッドを使用して、サーバーへの同期/非同期要求の両方を行い、deferred.resolve()を待機してから、遅延Promiseオブジェクトを返すことです。少し退屈に見えますが、大規模なデータの場合は少し勉強するのが確実です。 (この場合、tvanfossonの機能はうまく機能しますが、Googleの分析データに取り組んでいたとき、大量の情報に夢中になっていたため、この解決策を見つける必要があります)

_     function showResults(name) { 
        var deferred = $.Deferred, requests = [];

        requests.Push($.ajax({url:"/path/to/uri/?name=" + name, type: "GET", async: false}).done(function(d) { 
         //alert or process the results as you wish 
        }));
        $.when.apply(undefined, requests).then(function() { deferred.resolve(); }); 
        return deferred.promise();

    }
_

返されるpromiseオブジェクトは、$.when(showResults('benjamin')).done(function() { });とともに使用して、ポストの変更(チャート/グラフの設定など)にも使用できます。完全に再利用可能です。この関数を$ .deferredリクエストのループに入れることもできます。

_        function updateResults() { 
             var deferred = $.Deferred, requests = [];
             requests.Push($.ajax(url:"/path/to/names/?nameArr=" + jsonArrOfNames, type: "GET", async: false}).done(function(res) {  requests.Push(showResults(res[0]));}) );
             $.when.apply($, requests).then(function() { deferred.resolve(); }); 
             return deferred.promise();
            }
_
0
Cosmo Arun