我正在用JavaScript加载图片。如下所示:
images[0]=new Image();
images[0].onload=function(){loaded++;console.log(loaded)};
images[0].src="assets/img/image.png";
当我查看日志时,我看到所有的图像都被很好地加载了,因为“已加载”变量的值随着每个已加载图像的增加而增加。
然而,我想停止任何进一步的行动,直到这个数量达到它的最大值,所以在设置图像之后,我放置了一段时间循环。
while(loaded<11){
document.getElementById("test").innerHTML="Loading "+loaded+"/11";
console.log(loaded);
}
//Some code here which should only run after everything has been loaded
//In other words: when the statement in the while cycle becomes false
然而,我的浏览器完全崩溃了,因为while似乎陷入了无限循环。当我检查日志时,我看到"0“被写了1000次,在那之后,数字从1到11 (这意味着图像实际上被加载了,但while并不关心它,崩溃的速度比它发生的速度更快)。
我认为我在这里尝试使用的方法不是解决这个问题的正确方法。
在加载站点所需的所有资产之前,我如何将所有内容都搁置?
发布于 2016-06-16 17:04:29
就我个人而言,我讨厌使用while()...我认为最简单的方法是使用事件侦听器。
var img = new Image;
img.addEventListener("load", function () {
//Img loaded
});
img.src= e.target.result;
发布于 2019-05-28 19:42:35
使用promises和async函数,有一种很好的方法可以等待,直到加载完所有图像(没有回调,没有加载的图像计数):
async function loadImages(imageUrlArray) {
const promiseArray = []; // create an array for promises
const imageArray = []; // array for the images
for (let imageUrl of imageUrlArray) {
promiseArray.push(new Promise(resolve => {
const img = new Image();
// if you don't need to do anything when the image loads,
// then you can just write img.onload = resolve;
img.onload = function() {
// do stuff with the image if necessary
// resolve the promise, indicating that the image has been loaded
resolve();
};
img.src = imageUrl;
imageArray.push(img);
}));
}
await Promise.all(promiseArray); // wait for all the images to be loaded
console.log("all images loaded");
return imageArray;
}
或者,您可以等待加载单个图像:
async function loadImage(imageUrl) {
let img;
const imageLoadPromise = new Promise(resolve => {
img = new Image();
img.onload = resolve;
img.src = imageUrl;
});
await imageLoadPromise;
console.log("image loaded");
return img;
}
您可以这样使用它(使用promise链接):
loadImages(myImages).then(images => {
// the loaded images are in the images array
})
或者在异步函数中:
const images = await loadImages(myImages);
发布于 2016-06-16 17:32:06
Javascript是单线程的。这意味着,如果添加一个事件侦听器,则该侦听器在当前执行完成之前不会运行。因此,如果您启动一个依赖事件来结束它的循环,它将永远不会发生,因为事件永远不会触发,因为当前的执行正在阻止它运行。此外,事件是异步放置在调用堆栈上的,因此,如果您的执行速度慢于事件触发的速率(在调用堆栈上放置一个调用),则还存在页面崩溃的风险。当间隔设置为比代码执行所需的时间更短时,这是使用setInterval时的常见错误。切勿使用setInterval。
请记住,Javascript不能同时做两件事。
处理资源监控加载的最好方法是使用setTimeout。
var allLoaded = false;
var imgCount = 0; // this counts the loaded images
// list of images to load
const imageURLS =["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg"];
// array of images
var images = [];
const onImageLoad = function(){ imgCount += 1; } // onload event
// loads an image an puts it on the image array
const loadImage = function(url){
images.push(new Image());
images[images.length-1].src = url
images[images.length-1].onload = onImageLoad;
}
const waitForLoaded = function(){
if(imgCount === images.length){
allLoaded = true; // flag that the image have loaded
}else{
// display the progress here
...
setTimeout(waitForLoaded,100); // try again in 100ms
}
}
// create the images and set the URLS
imageURLS.forEach(loadImage);
setTimeout(waitForLoaded,100); // monitor the image loading
https://stackoverflow.com/questions/37854355
复制相似问题