我在onload
语句中有一个for
函数,会产生意外结果。
for
循环遍历图像数组。我希望这个循环为数组中的每个图像执行onload
,并且只有在for
循环完成后才进行下一次迭代。 onload
正在等待图像元素在执行之前加载。
for (index = 0; index < lightboxImages.length; index++) {
console.log('index :' + index);
// when the current image has finished loading
lightboxImages[index].onload = function() {
console.log('image ' + index + ' loaded.');
};
}
数组中只有三个元素,而我的console.log
语句在控制台中我期待这样的事情:
index : 0
image 0 loaded.
index : 1
image 1 loaded.
index : 2
image 2 loaded.
但我得到这样的输出:
index : 0
index : 1
index : 2
image 3 loaded.
image 3 loaded.
image 3 loaded.
如何在onload
完成之前阻止迭代?
我也试过这样的事情:
// just an index variable as an example
var counter = 2;
toImage(i) {
if (i == counter) {
console.log('hooray');
}
else {
toImage(i++);
}
}
toImage(0);
这导致了一个崩溃页面的callstack问题 - 我没有把它包含在原帖中,因为我认为这是一个完全独立的问题,但也许我应该回想起来。我想我在这里尝试递归是错误的。
答案 0 :(得分:1)
你可以用一个闭包解决这个问题。
var someFakeImages = [
{ onload: function () {} },
{ onload: function () {} },
{ onload: function () {} }
];
var onloadFunc = function(i) {
return function () {
console.log('image ' + i + ' loaded.');
}
};
for (index = 0; index < someFakeImages.length; index++) {
console.log('index: ' + index);
// when the current image has finished loading
someFakeImages[index].onload = onloadFunc(index);
}
someFakeImages[0].onload();
someFakeImages[1].onload();
someFakeImages[2].onload();
&#13;
您可以在MDN网站上找到有关闭包的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
基本上如上所述,您在分配onload处理程序时创建了一个带有index
值快照的新函数。在您发布的代码中,您实际上在执行 onload处理程序时使用了index
的当前值。
答案 1 :(得分:0)
另一种选择是递归调用:
&#xA;&#xA; 函数循环(lightboxImages,index){&#xA; if(index === lightboxImages.length)return;&#xA;&#xA; lightboxImages [index] .onload = function(){&#xA; console.log('image'+ index +'loaded。');&#xA;循环(lightboxImages,++ index);&#xA; } && xA;}&#xA;&#xA; loop(lightboxImages,0);&#xA;
&#xA;
答案 2 :(得分:0)
您的console.log显示索引的CURRENT值。你看,循环已经完成,当onloads被触发时,索引现在为3。您需要将索引作为LOCAL变量传递给onload处理程序。
对于许多程序员来说,处理异步编码是一个常见的“问题”;)
答案 3 :(得分:0)
分配给onload
只分配一个事件处理程序:它并不意味着当前线程停止并等待加载完成。我建议改用reduce
和await
。
function loadImages(lightboxImages) {
lightboxImages.reduce(async (lastPromise, image, i) => {
await lastPromise;
return new Promise((resolve, reject) => {
image.onload = () => {
console.log(`image ${i} loaded.`);
resolve();
};
});
}, Promise.resolve());
}