js循環里進行回調,引用循環里的變量,發現只是最后值的問題


做項目的時候,栽在一個小地方,是這樣的 

我有很多個坐標點,我想把這些坐標點都綁定一個事件,當點擊了這個坐標點之后,發送一個ajax 請求,將坐標點的id 發出去,等待顯示返回的數據

但是實際當中,無論我點擊了哪個點,都發現發送的ajax 請求都是最后一個點的id值上,

仔細一想,確實是這么回事,因為點擊這個事情是異步,當執行ajax的時候,遍歷早已結束,所以返回最后一點是正常的。

 

問題變成了,怎樣讓回調函數讀取到每次的臨時變量,也就是個閉包的問題

平時對閉包不是太清楚,所以順便復習一下了,

參考資料也是博客園朋友寫的   http://kb.cnblogs.com/page/110782/

之后也參考了這里 http://stackoverflow.com/questions/6978911/closure-inside-a-for-loop-callback-with-loop-variable-as-parameter

這里大概這么處理

在循環里寫

function build_callback(id){
  
returnfunction(data, textStatus){ alert(id);
  };
}
$.get("XXXX",build_callback(id))


 

也可以使用匿名函數解決

for (var idx=1; idx<=15; idx++)
    (function(idx) {
        var probeIP = siteConfigArray[idx].siteIP;
        if (probeIP != "" && probeIP != null)
            jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, 
                function(data, textStatus) { test(data, textStatus, idx); }, 'text'); 
        else // IP value is blank
            siteConfigArray[idx].portManifest = null;
    })(idx);

 

最后,如果有人用coffeescript 來寫,那就變得更簡單了,只需要在循環里在加一句 do (XXX) ->   

coffeescript就會自動生成好閉包,這里是我的代碼

for node in stations 
      do (node) ->
        point = new BMap.Point(node.lng,node.lat)
        marker = new BMap.Marker(point)
        label = new BMap.Label(node.name, {offset: new BMap.Size(20, 4)})
        marker.setLabel(label)
            
        contextMenu = new BMap.ContextMenu()
        contextMenu.addItem(new BMap.MenuItem("查看 #{node.name} 詳情", () ->                                                                                      
          $.get("stations/#{node.id}",(data)->
            eval data 
          )   

        , 200))
        window.map.addOverlay(marker)
        marker.addContextMenu(contextMenu)

 

coffeescript 也給出了官方例子 
for filename in list
  do (filename) ->
    fs.readFile filename, (err, contents) ->
      compile filename, contents.toString()

會對應生成這樣的js

var filename, _fn, _i, _len;

_fn = function(filename) {
  return fs.readFile(filename, function(err, contents) {
    return compile(filename, contents.toString());
  });
};
for (_i = 0, _len = list.length; _i < _len; _i++) {
  filename = list[_i];
  _fn(filename);
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM