下面是成功加載所有五個圖片代碼:for循環中的Ajax調用在表達爲函數時起作用,但不在for循環中直接放置時起作用。爲什麼?
for(i=0; i<5; i++) {
(function() {
var oReq = new XMLHttpRequest();
var r = "images/"+i+".jpg";
oReq.open("GET",r, true);
oReq.responseType = "arraybuffer";
oReq.send();
oReq.onload = function(oEvent) {
var blob = new Blob([oReq.response], {type: "image/jpg"});
var x = window.URL.createObjectURL(blob);
var img = new Image();
img.src = x;
img.width = 100;
$("#someDiv").append(img);
};
})();
}
這裏是代碼,只加載最後一個圖像:
for(i=0; i<5; i++) {
var oReq = new XMLHttpRequest();
var r = "images/"+i+".jpg";
oReq.open("GET",r, true);
oReq.responseType = "arraybuffer";
oReq.send();
oReq.onload = function(oEvent) {
var blob = new Blob([oReq.response], {type: "image/jpg"});
var x = window.URL.createObjectURL(blob);
var img = new Image();
img.src = x;
img.width = 100;
$("#someDiv").append(img);
};
}
爲什麼回調異步函數在for循環只有當代碼被放置在函數中而不是直接放置在循環中時才能工作?
因爲調用一個函數會創建一個新的作用域,給每個回調「自己的」oReq變量。請參見[JavaScript閉合內部循環 - 簡單實例](http://stackoverflow.com/q/750486/218196)。如果沒有它,'oReq'將始終引用最後一次迭代的值,因此'新Blob([oReq.response],{type:「image/jpg」});'總是收到最後一次請求的響應。 –
在ES6中注意,您可以通過使用'let'而不是'var'在循環中聲明所有變量來獲得所需的行爲。這也適用於相同的原因 - 每次關閉一個新變量而不是在每次迭代中捕獲同一個變量。 – PMV
其原因在於「變量的範圍」。當你將變量放在函數中時(就像你的情況一樣),每個變量都有自己的作用域(你的函數在循環中),但是當你直接使用它時,它會覆蓋同一個變量新的價值..結果你有最後的價值作爲結果 – RohitS