如何等待$ .getJSON()?

时间:2009-09-24 21:36:16

标签: jquery json

我有这个问题,我在这组选择上做了一个.each(),每个选项都会激活对服务器的调用,以便填充一些数据。但是我无法弄清楚为什么它只会填充最底层的那个。然后我扔了一些alert()并意识到它只是在最后一次多次运行回调函数。我意识到,当第一次JSON调用完成时,$(this)是不同的......我怎样才能让它等待所有这些都将被正确的调用填充?

这是脚本部分:

    var thisbundle;
    var testcount = 0;

    //get bundle options first..
    $("select.bundle").each(function(){

            thisbundle = $(this);
        testcount++;
            var url = "/order/getpricing/" + thisbundle.attr("id");

        //clear it out...
            //thisbundle.children().remove();

        var passbundle = thisbundle;
            $.getJSON(url, function(data, passbundle){
                var options = '';
                for(n = 0; n < data.length; n++){
                    options += '<option value="' + data[n].volumeID + '">' + explainPricing(data, n) + '</option>';

                    }
                passbundle.html(options);
        });
    });

这里是形式的一部分:

<div id="bundles">
<table>
    <%foreach (KODmvc.Models.Product prod in Model.products)
      {%>
            <%if (prod.NumberOfCourses > 1)
              { %>
                <tr><td><img src="<%=prod.Icon %>" /></td><td><b><%=prod.Title%></b><br /><%=prod.Description%></td><td><select class="bundle" id="<%=prod.ProductID %>"><option value="-1">None</option>"</select></td></tr>
            <%} %>
    <%} %>
    </table>
</div>

3 个答案:

答案 0 :(得分:3)

将ajax调用包含在这样的匿名函数中。这为每个select元素创建了一个新的闭包。每个闭包都会记住它自己passbundle的值。

$("select.bundle").each(function(){
    thisbundle = $(this);
    testcount++;
    var url = "/order/getpricing/" + thisbundle.val();
    alert(thisbundle.id);

    //clear it out...
    //thisbundle.children().remove();

    (function(){
        var passbundle = thisbundle;
        $.getJSON(url, function(data, passbundle){
            var options = '';
            for(n = 0; n < data.length; n++){
                options += '<option value="' + data[n].volumeID + '">' + explainPricing(data, n) + '</option>';
            }
            passbundle.html(options);
        });
    })();

});

答案 1 :(得分:2)

在您的函数中声明thisbundle而不是在全局范围内:

$("select.bundle").each(function(){
    var thisbundle = $(this);
    // …
});

否则全局对象将被回调函数随后使用的每次迭代覆盖。

答案 2 :(得分:1)

您也可以使用async:false,但如果您正在循环,则可能是错误的方向。但值得一看。