2013-05-14 77 views
-1

在擴展中,我在寫我需要驗證我存儲在localStorage中的一些對象與我的服務器存儲在一起。爲此,我創建了一個for循環,它簡單地爲每個本地存儲元素髮送數據,並且需要對響應進行一些操作。該代碼是這樣的:Ajax Inside For Loop

for (var key in localStorage) { 
     if (! some condition) 
         continue; 

     var httpRequest = new XMLHttpRequest(); 
     httpRequest.onreadystatechange = function() { 
      if (httpRequest.readyState === 4 && httpRequest.response == 200) { 
       do something with 'key' from the for loop 
      } 
     } 
     }; 
     var url = BASE_PATH ; 
     httpRequest.open("POST", url); 
     httpRequest.send(some data); 
        } 

但是在調試似乎在Ajax響應,從for循環的「鑰匙」是不是我需要的關鍵是:我期待得到相同的密鑰與每個ajax調用匹配的for循環,我得到的是所有ajax調用的相同鍵。 我做錯了什麼或期待什麼是不可能的?我認爲,因爲ajax在關閉函數內部,所以值被保存在內存中或類似的東西中。

+0

可能重複[Javascript閉合內部循環 - 簡單實用的例子](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – 2013-05-14 14:49:57

+0

有一個「)」 (httpRequest.readyState === 4)&& httpRequest.response == 200) – 2013-05-14 14:52:52

回答

1

提取實際Ajax調用一個單獨的函數:

function AjaxCall(key) { 
    var httpRequest = new XMLHttpRequest(); 
    httpRequest.onreadystatechange = function() { 
    if ((httpRequest.readyState === 4) && (httpRequest.response == 200)) { 
     do something with 'key' from the for loop 
    } 
    }; 
    var url = BASE_PATH ; 
    httpRequest.open("POST", url); 
    httpRequest.send(some data); 
} 

for (var key in localStorage) { 
    if (some condition) {  
    AjaxCall(key); 
    }  
} 

原因是,你正在創建一個傳遞給onreadystatechange功能的關閉。所有這些函數都指向相同的key變量,該變量在循環完成後僅保留所有Ajax調用的一個(最後一個)值。

當您創建一個單獨的函數(如我的示例中的AjaxCall())時,您爲每個調用創建一個不同的上下文,因此所有回調指向不同的鍵。

+0

正如我在問題中所說的那樣,有一個)不應該在那裏。此外,「else」不是必需的,因爲如果達到了繼續,下面的代碼將不會被執行。但是,很好的解釋。 – 2013-05-14 14:57:35

+0

另外,在for循環中,如果您尚未使用hasOwnProperty方法,則可能需要嘗試。這將阻止您發送從對象類型繼承的屬性名稱或函數名稱。 – jhorton 2013-05-14 14:57:44

+0

@jhorton:在Object.prototype中定義的本地屬性都不可枚舉。只要在原型上沒有定義可枚舉的屬性,就可以。 – 2013-05-14 15:00:22