jQuery.ajax()中的范围问题

时间:2010-10-12 19:19:59

标签: javascript jquery ajax closures

我通过将标签字符串保存到变量中来缓存标签字符串,但遇到了奇怪的范围问题。我知道这与闭包有关,但我似乎无法弄清楚究竟是什么问题。

info_lbl = {};

$("#chkCorporateGift").click(function(){
    var type = $(this).is(":checked") ? "Corporate" : "Personal";
    if(!info_lbl.hasOwnProperty(type)){
        $.ajax({
            url: svc_og + "Get" + type + "InformationLabel",
            success: function(data){
                info_lbl[type] = data;
            }
        });
    }
    $("#lblInformationType").text(info_lbl[type]);
});
第一次调用GetCorporateInformationLabel或GetPersonalInformationLabel方法时,未设置lblInformationType标签。在第一次调用每个人之后,标签的值正在改变。有人可以解释为什么会出现这种情况吗?当我使用Firebug并在$("#lblInformationType").text(info_lbl[type]);上设置断点时,info_lbl[type]包含正确的值,并且前两个调用的一切正常。

3 个答案:

答案 0 :(得分:5)

AJAX调用是异步的。这意味着请求后面的任何代码都 not 等待请求在运行之前返回。

换句话说,AJAX请求不会阻止后续代码行的执行。因此,当从AJAX请求收到响应时,已经执行了以下代码行。

任何依赖于AJAX请求响应的代码都应该放在里面回调中。

$("#chkCorporateGift").click(function(){
 //   var type = $(this).is(":checked") ? "Corporate" : "Personal";
    // It is more efficient to use this.checked instead of using .is(":checked")
    var type = this.checked ? "Corporate" : "Personal";
    if(!info_lbl.hasOwnProperty(type)){
        $.ajax({
            url: svc_og + "Get" + type + "InformationLabel",
            success: function(data){
                info_lbl[type] = data;
                  // code that relies on the response needs to be placed in
                  //   a callback (or in a function that is called here).
                $("#lblInformationType").text(info_lbl[type]);
            }
        });
    } else {
        $("#lblInformationType").text(info_lbl[type]);
    }
});

我会想到,当你有一个断点时,事情正常工作的原因是执行中的暂停会让AJAX响应时间返回。


编辑:使用this.checked代替原始$(this).is(':checked'),提高了代码的效率。

答案 1 :(得分:1)

移动此行:

        $("#lblInformationType").text(info_lbl[type]);
进入“成功”回调。

答案 2 :(得分:1)

如上所述,有两种解决方案:

1)使$ .ajax异步

$.ajax({
    url: svc_og + "Get" + type + "InformationLabel",
    async: false,
    success: function(data){
        info_lbl[type] = data;
    }
});

2)保持异步,但要做两次:

var type = $(this).is(":checked") ? "Corporate" : "Personal";
if(!info_lbl.hasOwnProperty(type)){
    $.ajax({
        url: svc_og + "Get" + type + "InformationLabel",
        success: function(data){
            info_lbl[type] = data;
            $("#lblInformationType").text(data);
        }
    });
}
$("#lblInformationType").text(info_lbl[type]);