下面是成功加载所有五个图片代码: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