开发者

How to access a closure variable from within a callback

I am looping through an array of urls. Each one fetches some jsonp data from a different domain. The success handler needs to be able to access the data in the original loop, however when called from the callback it is always the last value and not the value that was set when the ajax function was called. How do I access or pass this value to the callback?

for(var site in data.sites){
    var domain =  data.sites[site].domain;
    $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
    $.getJSON(url, function(data){
        if(data.success == true)
            $("#" +  domain.replac开发者_如何学JAVAe(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
        else
            $("#" +  site.domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
    });
}


In JavaScript there's no block scope for your for loop, the domain variable is shared for all loops, it's scoped to the parent function, not strictly inside the loop (for example you could access it after the closing } for the for() and it'd be the value it had in the last loop).

To resolve this, you need to create an additional scope with it's own variable; using $.each() is easiest in this case:

$.each(data.sites, function(i, site){
  var domain = site.domain;
  $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
  $.getJSON(url, function(data){
    if(data.success == true)
        $("#" + domain.replace(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
    else
        $("#" + domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
  });
});

The for loop way would be like this:

for(var site in data.sites){
  (function(domain) {
    $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
    $.getJSON(url, function(data){
        if(data.success == true)
            $("#" +  domain.replace(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
        else
            $("#" + domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
    });
  })(data.sites[site].domain);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜