如何等待onload语句完成

时间:2018-03-20 22:04:55

标签: javascript

我在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问题 - 我没有把它包含在原帖中,因为我认为这是一个完全独立的问题,但也许我应该回想起来。我想我在这里尝试递归是错误的。

4 个答案:

答案 0 :(得分:1)

你可以用一个闭包解决这个问题。

&#13;
&#13;
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;
&#13;
&#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只分配一个事件处理程序:它并不意味着当前线程停止并等待加载完成。我建议改用reduceawait

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());
}