通过 AJAX 请求创建映像后,等待映像加载



我正在通过 AJAX 请求获取图像(74 个文件(。我正在将它们加载到数组中。然后我更改一些调用函数的样式changeMargins().问题是,当图像尚未全部加载并准备就绪时,将调用该函数。

imageArray = new Array();     
$.ajax({
url: url,
success: function (data) {
counter = 0
$(data).find("a").attr("href", function (i, val) {
if (val.match(/.(jpe?g|png|GIF)$/)) { 
imageArray[counter]= new imageItem(url + val)
++counter;  
}
});
changeMargins(imageArray);

如何等待 AJAXImage 元素上的所有加载事件完成,然后继续处理?

这个问题可能最好通过"承诺"图像加载过程来解决,即创建一个在图像加载时解决的承诺。

有一个设计决策要做...是 (a( 吞下负载错误还是 (b( 允许任何单个错误导致整个过程失败。

假设(a(,你会写这样的东西:

function loadImages() {
return $.ajax({
url: url,
// other ajax params?
}).then(function(data) {
return $.Deferred(function(dfrd) { // promisify the entire image loading proceess
var imageArray = [];
var counter = 0; // tally of images that have either loaded or failed to load
$(data).find('a').get().map(function(element) {
// map a elements in data to an array of their hrefs
return element.href;
}).filter(function (href) {
// filter out any non-jpe?g|png|GIF 
return href.match(/.(jpe?g|png|GIF)$/);
}).forEach(function(val) {
// for each match, create a Image() object, push onto the array, attach onload and onerror handlers, and set the `src` attribute.
var img = new Image();
imageArray.push(img);
img.onload = function loadHandler() {
counter += 1;
if(counter == images.length) {
dfrd.resolve(imageArray);
}
};
img.onerror = function errorHandler() {
console.log(new Error('image ' + url + val + ' failed to load'));
// Here, you might choose to splice failed Images out of `imageArray`.
counter += 1;
if(counter == images.length) {
dfrd.resolve(imageArray);
}
};
img.src = url + val;
});
});
}).then(function(imageArray) {
changeMargins(imageArray);
return imageArray;
});
}

笔记:

  • 更典型的是,人们会选择在最低级别(即每个 Image(( 单独(承诺,但承诺相当昂贵,因此对于 74 张图像,最好集体承诺。
  • 通过承诺,并从loadImages()返回一个承诺,它的调用者被告知该过程的完成 - 你可以链接loadImages().then(...)并在图像加载/失败时做一些事情。

最新更新