0

以下のコードに問題があります。

jQuery.each は、JSON 要求が完了するのを待たずに高速化しています。その結果、'thisVariationID' および 'thisOrderID' 変数は、低速な getJSON 関数で使用できるようになる前に、ループの最新の反復によってリセットされます。

次の反復に進む前に、getJSON リクエストとコールバック関数が完了するまで .each の各反復を待機させる方法はありますか?

$.each($('.checkStatus'), function(){
            thisVariationID = $(this).attr('data-id');
            thisOrderID = $(this).attr('id');
            $.getJSON(jsonURL+'?orderID='+thisOrderID+'&variationID='+thisVariationID+'&callback=?', function(data){
                if (data.response = 'success'){
                //show the tick. allow the booking to go through
                    $('#loadingSML'+thisVariationID).hide();
                    $('#tick'+thisVariationID).show();
                }else{
                //show the cross. Do not allow the booking to be made
                    $('#loadingSML'+thisVariationID).hide();
                    $('#cross'+thisVariationID).hide();
                    $('#unableToReserveError').slideDown();
                    //disable the form
                    $('#OrderForm_OrderForm input').attr('disabled','disabled');
                }
            })
        })
4

4 に答える 4

3

1) のいずれかを使用する必要があります。非非同期呼び出し (次のコードに示すように):

$.ajax({
    url:jsonURL, 
    dataType:'json', 
    data:{orderID:thisOrderID, variationID:thisVariationID},
    async:false,
    success:function()
    {
        // do stuff.
    }

2)。jsonp クロス サイトを使用している場合は、それぞれを使用する代わりに呼び出しをチェーンする必要があります。each を使用してデータ配列を作成し、json の呼び出しを開始します。各反復では、コールバックで前のデータを使用します。


追加: 操作の明確化のために、処理するアイテムのリストを設定し、それらを個別に処理するクロスサイト実装。

私は主に Plain Old Javascript に分割しました。これは、この状況で読みやすいと思われるものです。

var items = [];
function setUp()
{
    items = [];  // clear in case this gets recalled.
    $('.checkStatus').each(function(idx, el){
         values.push({variationID:$(el).data('id'), orderID:$(el).attr('id')});
    }
    if (items.length > 0)
    {
        consume();
    }
}
function handleResponse(data)
{
    // do your data handling and formatting here.
    if (items.length >= 0) consume();
}
function consume()
{
    var thisOrder = items.pop();
    $.ajax({
        url:jsonURL, 
        dataType:'jsonp', 
        data:{orderID:thisOrder.orderID, variationID:thisOrder.variationID},
        async:false,
        success:handleResponse
    });
}
setUp();

これらはすべてグローバル名前空間に配置されていますが、クロージャまたは関数の内部に簡単に配置できることに注意してください (つまり、全体を $(document).ready() でラップします)。

于 2012-06-05T04:37:28.280 に答える
3

迅速な修正のために 2 つの変更点が 2 つあります。

  1. 変数の前に使用varして、変数をグローバルではなくローカルにします。そうすれば、反復ごとに新しい変数インスタンスを取得できます。varグローバル名前空間を本当に汚染するつもりがない限り、常に使用してください。

        var thisVariationID = $(this).attr('data-id');
        var thisOrderID = $(this).attr('id');
    
  2. ;)==の代わりに比較するために使用します=

        if (data.response == 'success'){
    

見落としていると思われるこれらの問題を修正した後、コードが意図したとおりに機能し始める可能性が高くなります。ただし、より大幅な変更を希望する場合は、 Deferredsを使用することもできます。

一連のフェッチを並行して実行するには:

var fetches = $('.checkStatus').map(function () {
    var thisVariationID = $(this).attr('data-id'),
        thisOrderID = $(this).attr('id');

    return $.getJSON(/* blah blah */);
});

fetches = $.when.apply($, fetches);

fetches.done(function () {
    // all parallel fetches done
});

フェッチをシリアル化するには:

var fetching = $.when();

$('.checkStatus').each(function () {
    var thisVariationID = $(this).attr('data-id'),
        thisOrderID = $(this).attr('id');

    fetching = fetching.pipe(function () {
        return $.getJSON(/* blah blah */);
    });
});

fetching.done(function () {
    // last fetch done
});

やり過ぎ?多分。しかし、それは柔軟であり、「フェッチが完了したとき」を文字通り読み取るコードを持つという構文糖衣の価値がある場合があります。

(注: 上記の実装は、説明のみを目的とした楽観的な実装です。実際の実装では、失敗も処理する必要があります。)

于 2012-06-05T04:50:58.607 に答える
0

非同期メカニズムを非アクティブ化する必要があります。こちらをご覧ください:https ://stackoverflow.com/a/933718/1343096

于 2012-06-05T04:35:22.493 に答える
0

答えの代わりになぜそこに行ったのかわからない私のコメントを参照してください。ここでは同期化したので、応答を待ちます。

jQuery:続行する前に、$.get の読み込みが完了するのを待つことは可能ですか?

于 2012-06-05T04:37:47.557 に答える