0

我对以下代码有疑问:

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

4 回答 4

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() 中)。

于 2012-06-05T04:37:28.280 回答
3

两件事改变了两个快速修复:

  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 回答