考虑以下代码:

function func() {
    var totalWidths = 0;
    for( var i = 0, count = arr.length; i < count; i++ ) {
        var image = arr[i];

        insertElemInDOM(image);

        preloadImage(image,function(){
            var w = image.width();
            totalWidths += w;
        });

    }
    // do something with the variable "totalWidths"
    doSomething(totalWidths)
}


我这里有两个问题。图像将始终相同(第一个问题),可以使用匿名函数解决该问题:

    for(...) {
        (function(image) {
            preload(image,function() {
                // now image is the correct one
            });
        })(image);
    }


但是,如何管理totalWidths变量以便稍后在doSomething(totalWidths)上使用它?先前的代码的totalWidths值为0。
谢谢!

最佳答案

您可以使整个循环和doSomething超时,这比设置这么多的超时要好得多:

setTimeout(function() {
    var inc = 0;
    for (var i = 0; i < count; i++) {
        var w = arr[i].width();
        inc++;
    }
    doSomething(inc);
}, 1000);




但是,您实际上想要的是嵌套超时,即每个迭代步骤等待1秒,然后完成所有操作:

var inc = 0, count;
function asyncLoop(i, callback) {
    if (i < count) {
        var w = arr[i].width();
        inc++;
        setTimeout(function() {
            asyncLoop(i+1, callback);
        }, 1000);
    } else {
        callback();
    }
}
asyncLoop(0, function() {
    doSomething(inc);
});




好的,现在我们知道您需要的解决方案是在每个加载事件之后检查是否所有图像都已加载:

var totalWidths = 0,
    count = arr.length,
    loaded = 0;
for (var i = 0; i < count; i++)
    (function (image) {
        insertElemInDOM(image);
        preload(image, function() {
            totalWidths += image.width();
            // counter:
            loaded++;
            if (loaded == count-1) // the expected value
                doSomething(totalWidths); // call back
        });
    })(arr[i]);

10-06 00:02