jquery-成功時のajax結果を使用した戻り値


95

jquery $ .ajax()関数に小さな問題があります。

ラジオボタンをクリックするか、ドロップダウンメニューから選択するたびに、選択した値でセッション変数を作成するフォームがあります。

今、私は4つのオプションがあるドロップダウンメニューの1つを持っています-最初のもの(ラベルなし)にはvalue = ""があり、他にはIDがあります。

私がしたいのは、セッションを削除するためのNoneオプション(空白の値)で、セッションを作成するためのものですが、この特定の選択名を持つセッションがまだ存在していない場合のみです。他のすべてのオプションには同じ量が割り当てられているためです。 -どれが選択されたかを示すだけです。

それが理にかなっているのかどうかはわかりませんが、コードを確認してください。おそらく、これでわかりやすくなります。

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();


        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            if(isSession(name) == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
});

つまり、まず#add_ons selectメニューが「変更」をトリガーすると、計算のためにいくつかの要素からいくつかの値を取得します。

合計に追加する値を格納するselectからオプションのlabel属性を取得します。この名前と値でセッションを作成するselectの名前と、後で選択されたものを確認します。

ここで、val == ""([なし]オプションが選択されていることを示す)かどうかを確認し、合計から金額を差し引くとともに、selectの名前を持つセッションを削除します。

この後、問題が始まります-elseステートメント。

それ以外の場合-セレクターの名前を持つisSession()関数が0または1を返すかどうかを確認します。0を返す場合は、label属性に格納されている値の合計に追加しますが、1を返す場合は、そのセッションはすでに存在します-次に、このセッションの値を変更するだけで、セッションを再作成します-量は追加されません。

isSession関数は次のようになります。

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

さて-問題は-「return」を使用しても関数から結果が返されるかどうかがわからないことです-機能していないようです-しかし、「data」を成功に挿入した場合:セクションにアラート-正しい値を返すようです。

関数から値を返し、次のステートメントでそれを比較する方法を誰かが知っていますか?


みんなありがとう-私は次の方法でそれを試しました:

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            updateResult(data);
        },
        error: function() {
            alert('Error occured');
        }
    });
}

次にupdateResult()関数:

function updateResult(data){結果=データ; }

結果-グローバル変数です-私はそれを読み込もうとしています:

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();


        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            isSession(name);
            if(result == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
    });

しかし、何らかの理由で-それは機能しません-アイデア?



この問題の解決に役立つ可能性があります。stackoverflow.com / questions / 14220321 /
mirzaei.sajad

回答:


113

問題は、AJAXリクエストのように、非同期呼び出しから値を返すことができず、機能することを期待できないことです。

その理由は、応答を待機しているコードが、応答を受信するまでにすでに実行されているためです。

この問題の解決策は、コールバック内で必要なコードを実行することですsuccess:。このようにして、アクセスdata可能な場合にのみアクセスします。

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            // Run the code here that needs
            //    to access the data returned
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

別の可能性(これは実質的に同じことです)はsuccess:、データが使用可能なときにデータを渡すコールバック内の関数を呼び出すことです。

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
                // Call this function on success
            someFunction( data );
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

function someFunction( data ) {
    // Do something with your data
}

11
AJAXリクエストから値を返すことはできますが、それを非同期にしない場合のみです(オプションを設定async: false)。場合によっては、非同期呼び出しが必須ではありません。jquery.ajax()の詳細doc api.jquery.com/jQuery.ajax、それではありませんAs of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;
Adrien Be

48
「非同期」はもちろん「同期」とも呼ばれます;)
Charles Wood

あなたが提案した両方の方法で; すなわち。関数を実行して成功したら、さまざまなシナリオで複数のajaxを作成する必要があります。これは、グローバルなajaxラッパー、エンジンの作成には役立ちません。
wpcoder

どうやら、async:falseは非推奨になり、すべての処理はコールバック関数で行う必要があります。
Puneet Lamba

31

jQuery AJAX応答を取得するには多くの方法があります。2つの一般的なアプローチを紹介します。

最初:

async = falseを使用し、関数内でajax-objectを返し、後で応答ajax-object.responseTextを取得します

/**
 * jQuery ajax method with async = false, to return response
 * @param  {mix}  selector - your selector
 * @return {mix}           - your ajax response/error
 */
function isSession(selector) {
    return $.ajax({
        type: "POST",
        url: '/order.html',
        data: {
            issession: 1,
            selector: selector
        },
        dataType: "html",
        async: !1,
        error: function() {
            alert("Error occured")
        }
    });
}
// global param
var selector = !0;
// get return ajax object
var ajaxObj = isSession(selector);
// store ajax response in var
var ajaxResponse = ajaxObj.responseText;
// check ajax response
console.log(ajaxResponse);
// your ajax callback function for success
ajaxObj.success(function(response) {
    alert(response);
});

第二:

$ .extend メソッドを使用して、ajaxのような新しい関数を作成する

/**
 * xResponse function
 *
 * xResponse method is made to return jQuery ajax response
 * 
 * @param  {string} url   [your url or file]
 * @param  {object} your ajax param
 * @return {mix}       [ajax response]
 */
$.extend({
    xResponse: function(url, data) {
        // local var
        var theResponse = null;
        // jQuery ajax
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            dataType: "html",
            async: false,
            success: function(respText) {
                theResponse = respText;
            }
        });
        // Return the response text
        return theResponse;
    }
});

// set ajax response in var
var xData = $.xResponse('temp.html', {issession: 1,selector: true});

// see response in console
console.log(xData);

好きなだけ大きくすることができます...


素晴らしいアイデアajaxObj['responseText']ですが、定義しているときには存在しませんvar ajaxResponse
mu3

パーフェクト!! 最初の解決策が私を救った
Kallel Omar

2つ目の方法は100%Aです。;)
Schalk Keun、

7
jQuery 1.8以降、async:falseの使用は非推奨になりました!
ガッテオ2017

10

私はここで答えを確認しましたが、役に立ちましたが、コードの多くを変更しなければならなかったので、それらは私が望んでいたものとはまったく異なりました。

私にとってうまくいったのは、次のようなことでした:

function isSession(selector) {
    //line added for the var that will have the result
    var result = false;
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        //line added to get ajax response in sync
        async: false,
        success: function(data) {
            //line added to save ajax response in var result
            result = data;
        },
        error: function() {
            alert('Error occured');
        }
    });
    //line added to return ajax response
    return result;
}

希望は誰かを助けます

アナキン


4
実際には非同期をオフにするだけです
Weijing Jay Lin

4

の使用に関するすべてのアプローチasync: falseはその非推奨のために良いものではありませんが、リクエストが返されるまでページをスタックしました。したがって、これを行うには2つの方法があります。

1つ目:関数でajax応答全体を返し、関数を使用doneして、要求が完了したときに応答をキャプチャします。(推奨、最高の方法)

function getAjax(url, data){
    return $.ajax({
        type: 'POST',
        url : url,              
        data: data,
        dataType: 'JSON',
        //async: true,  //NOT NEEDED
        success: function(response) {
            //Data = response;
        }
    });
 }

上記のように呼び出す:

getAjax(youUrl, yourData).done(function(response){
    console.log(response);
});

複数のAJAX呼び出しの場合$.when

$.when( getAjax(youUrl, yourData), getAjax2(yourUrl2, yourData2) ).done(function(response){
    console.log(response);
});

2番目:Cookieに応答を格納し、ajax呼び出しの外側でそのCookie値を取得します(非推奨)。

        $.ajax({
            type: 'POST',
            url : url,              
            data: data,
            //async: false,    // No need to use this
            success: function(response) {
                Cookies.set(name, response);
            }
        });

        // Outside of the ajax call
        var response = Cookies.get(name);

注:上記のjquery cookies例ではライブラリが使用されています。非常に軽量で、きびきびと動作します。ここにリンクがありますhttps://github.com/js-cookie/js-cookie


3

async: false属性リストに追加します。これにより、JavaScriptスレッドは戻り値が取得されるまで待機してから次に進みます。明らかに、すべての状況でこれを実行する必要はありませんが、続行する前に値が必要な場合は、これで実行されます。


3
決して設定してはいけませんasync: false。これにより、検索の間、ページ上のすべての機能がブロックされます。あなたはAJAXのAが何を意味するか知っています:非同期。適切な答えは、OPがsuccess()コールバックを適切に使用する必要があるということです。
nietonfir 2013年

2
私はすべてが待たなければならないという事実を認めました。特定の状況下では、新しいレコードを追加したり、レコードIDを返す必要があるなど、呼び出し元の関数が戻り値を必要とする場合があります。ルールが分かれば、いつルールを破ることができるかわかります。絶対とは絶対言うな。ここで同意する他の誰かがいます。(stackoverflow.com/questions/3880361/...
HOODLUM

1
@CharlesWood Ajaxの非同期の性質を理解できない人のためにのみ。
nietonfir 14

1
@nietonfir:決して使用すべきではない場合async: false、なぜjQueryがこのオプションを実装するのでしょうか?ページに大量のデータを読み込まずにユーザーイベントを処理するだけの場合、その特定のユーザーの短時間で他のすべてをブロックすることは問題ありません。それについて何も悪いことも悪いこともありません。(正しく使用すると、その特定の時間内にその特定のユーザーに対して他のアクションが発生しないため、何もブロックされません)
low_rents

1
@northkildonanいいえ、大丈夫ではありません。同期AJAXリクエストは不正です。それはあなたが制御できない何かで完全なjavascriptスレッドをブロックします。リクエストの処理にかかる時間を制御できません。接続が信頼できない、サーバーが予想よりも時間がかかるなどです。それがjQueryにある唯一の理由は、データを保存する必要があるかもしれないということですページのアンロード時(ユーザーが既にページを離れたいという希望を表明しているため、時間がかかるかどうかは問題ではない唯一の場所です)。ただ... jQueryのユニットテストを見て
nietonfir

3

これはかなり古く、醜いので、これを行わないでください。コールバックを使用する必要があります:https :
//stackoverflow.com/a/5316755/591257同じ問題があり、グローバル変数を使用してこの方法で解決しました。それが最高かどうかはわかりませんが、確実に機能します。エラーが発生すると空の文字列(myVar = '')が返されるため、必要に応じて処理できます。

var myVar = '';
function isSession(selector) {
  $.ajax({
    'type': 'POST',
    'url': '/order.html',
    'data': {
      'issession': 1,
      'selector': selector
    },
    'dataType': 'html',
    'success': function(data) {
      myVar = data;
    },
    'error': function() {
      alert('Error occured');
    }
  });
  return myVar;
}

3
async: false非同期モードでdataは、myVar以前に保存されていることmyVarが返されることが保証されていないため、ここにも追加する必要があります。
low_rents 2014

2
// Common ajax caller
function AjaxCall(url,successfunction){
  var targetUrl=url;
  $.ajax({
    'url': targetUrl,
    'type': 'GET',
    'dataType': 'json',
    'success': successfunction,
    'error': function() {
      alert("error");
    }
  });
}

// Calling Ajax
$(document).ready(function() {
  AjaxCall("productData.txt",ajaxSuccessFunction);
});

// Function details of success function
function ajaxSuccessFunction(d){
  alert(d.Pioneer.Product[0].category);
}

それは役立つかもしれません、一般的なajax呼び出し関数を作成し、ajax呼び出しが成功したときに呼び出す関数をアタッチします。例を参照してください


1

ここからの助けを借り

function get_result(some_value) {
   var ret_val = {};
   $.ajax({
       url: '/some/url/to/fetch/from',
       type: 'GET',
       data: {'some_key': some_value},
       async: false,
       dataType: 'json'
   }).done(function (response) {
       ret_val = response;
   }).fail(function (jqXHR, textStatus, errorThrown) {
           ret_val = null;
       });
   return ret_val;
}

これが誰かを少し助けてくれることを願っています。


の使用async: false,は先史時代のものであり、jQuery v1.8以降は非推奨です。おそらく誰も役に立たないでしょう
Alon Eitan

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.