2014-02-17 188 views
13

我剛剛使用AJAX,並且正在編寫一個腳本,它將處理頁面上的一堆鏈接,併爲每個鏈接創建AJAX調用。jQuery AJAX調用for循環

for (var i = 0; i < linkList.length; i++) 
{ 
    $.ajax({ 
     url: linkList[i].getAttribute("href"), 
     cache: false 
    }).done(function(html) 
    { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) 
     { 
      hasAppended = true; 
      var id = linkList[i].getAttribute("href").substring(linkList[i].getAttribute("href").indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
} 

試圖簡單地說,我有一個包含鏈接列表的頁面。我希望遍歷鏈接並獲取AJAX處理每個鏈接頁面的內容,並在該頁面包含指定的內容時返回。

我遇到的問題是[i]用於遍歷linkList的值始終爲6,並且它永遠不會。我假設我需要傳遞一些數據,以便當.done最終觸發時,它知道AJAX第一次觸發時的[i]值,而後面​​的.done觸發時不知道[i]的值。

如何確保.done在首次調用AJAX時知道它是[i]值?

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake –

+0

是什麼'鏈接List'是一個jQuery對象還是一個數組? –

+0

解決方案可能看起來像http://jsfiddle.net/arunpjohny/2Da7Z/1/ –

回答

35

最簡單的方法是使用閉包。每當你在循環中有異步時,它就是同樣的事情。

for (var i .....) { 
    async(function() { 
    use(i); 
    } 
} 

在該僞代碼片段中,內部函數捕獲由i引用的存儲位置。循環運行時,i遞增到最終值,然後異步回調開始被調用,所有這些查找完全相同的位置(不是值)。

一般的解決方法是這樣的:

for (var i .....) { 
    (function (i) { 
    async(function() { 
     use(i); 
    }); 
    })(i); 
} 

即包裹你的循環的全部內容在一個自動執行功能。

在這裏,外部i被傳遞到包裝自我執行的匿名函數;這個唯一值的位置被異步回調捕獲。通過這種方式,每個異步都獲得自己的值,這是在調用自執行函數時確定的。

+4

添加(函數(i){代碼})(i);包裝器完美地工作,現在代碼以預期的結果運行。謝謝! – Edge

+5

所以這是關閉的點 – LazerSharks

+0

你救了我的生命 – krummens

11

問題的評論部分中的鏈接告訴您代碼中出現了什麼問題......但您可以有一個比以前解釋的更好的解決方案。

嘗試$.each()列表以迭代(假設它是一個數組),以使通過了回調將針對每次迭代

$.each(linkList, function (i, item) { 
    $.ajax({ 
     url: item.getAttribute("href"), 
     cache: false 
    }).done(function (html) { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) { 
      hasAppended = true; 
      var id = item.getAttribute("href").substring(item.getAttribute("href").indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
}) 

創建一個單獨的封閉如果它是一個jQuery對象,然後使用.each()

linkList.each(function (i, item) { 
    var $item = $(item), 
     href = $item.attr("href"); 
    $.ajax({ 
     url: href, 
     cache: false 
    }).done(function (html) { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) { 
      hasAppended = true; 
      var id = href.substring(href.indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
})