当表示为函数时,for循环中的Ajax调用工作,但直接放在for循环中时则不工作。为什么?

时间:2016-12-28 19:05:04

标签: javascript

以下是成功加载所有五张图片的代码:

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循环中的异步函数只能在代码放在函数中而不是直接放在循环内部时才能工作?

1 个答案:

答案 0 :(得分:2)

在第一种情况下,存在与循环迭代一样多的oReq变量,因为每次调用包装函数((function() {...})())时,它都会创建一个包含新的oReq变量。

在第二种情况下,有一个oReq变量可以重复使用,并在循环的每次迭代中设置为一个新值。

这很重要,因为它确定oReqnew Blob([oReq.response], ...);处理程序中执行onload时所引用的值。在第一种情况下,它引用匿名包装函数的oReq本地,因此每个onload函数引用唯一的oReq。在第二种情况下,所有onload回调都引用单个oReq值,该值保存oReq

中存储的单个最终值