$ .each - 在继续之前等待jSON请求

时间:2012-06-05 04:31:11

标签: jquery json each

我遇到以下代码的问题:

jQuery.each正在加速,而不等待JSON请求完成。因此,'thisVariationID'和'thisOrderID'变量将被循环的最新迭代重置,然后才能在较慢的getJSON函数中使用。

有没有办法让.each的每次迭代等到getJSON请求和回调函数完成后才转到下一次迭代?

$.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 个答案:

答案 0 :(得分:3)

你需要使用其中之一 1)。非异步调用(如以下代码所示):

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

2)。如果您正在使用jsonp跨站点,则需要链接您的呼叫而不是使用每个呼叫。使用each来构建一个数据数组,然后开始调用json,每次迭代都使用回调中之前的数据。


补充:为了澄清,一个跨站点实现,它设置要处理的项目列表,然后单独处理它们。

我已经进入了大多数普通的旧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()中)。

答案 1 :(得分:3)

快速解决方法有两个变化:

  1. 在变量之前使用var使其成为本地而非全局变量。这样,您将为每个迭代获取新的变量实例。除非您真的打算污染全局命名空间,否则始终使用var

        var thisVariationID = $(this).attr('data-id');
        var thisOrderID = $(this).attr('id');
    
  2. 使用==进行比较而不是=;)

        if (data.response == 'success'){
    
  3. 在解决您似乎忽略的这些问题后,您的代码很可能会按预期开始工作。但是,如果你愿意采取更激烈的改变,你也可以使用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
    });
    

    过度破坏?也许。但它很灵活,有时可能值得使用代码的语法糖,字面意思是“当我的提取完成时”。

    (注意:上述实现只是一个乐观的实现,仅用于说明目的。在实际实现中,您还应该处理失败。)

答案 2 :(得分:0)

您只需停用异步机制即可。 看看这里:https://stackoverflow.com/a/933718/1343096

答案 3 :(得分:0)

看我的评论我不知道为什么它去那里而不是回答。 这里它是同步的,所以它等待响应。

jQuery: Possible to wait for $.get to finish loading before continuing?