【问题标题】:$.each - wait for jSON request before proceeding$.each - 在继续之前等待 JSON 请求
【发布时间】:2012-06-05 04:31:11
【问题描述】:

我对以下代码有疑问:

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

【问题讨论】:

标签: jquery json each


【解决方案1】:

为了快速修复,两件事发生了两个变化:

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

矫枉过正?可能。但它是灵活的,有时可能值得拥有字面意思是“当我的提取完成时”的代码的语法糖。

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

【讨论】:

    【解决方案2】:

    您需要使用 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() 中)。

    【讨论】:

    • 它是跨站点的。我不确定我是否遵循您对 2 的解释。如果可能,您能否提供一个示例?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多