我陷入了纠结,可能涉及多个异步回调情况。
我有一个名为populatePageArea()的javascript函数
在populatePageArea中,它遍历这个类似于数组的变量,在其他代码中称为pages。
function populatePagesArea() {
// there was some code before the for loop
for (var i=0, l=pages.length; i<l; i++) {
addToPagesArea(pages[i], "");
}
// some code after...
}
在addToPagesArea函数中,我使用HTML 5中的FileAPI来预览拖放文件和其他代码。
function addToPages(file, front) {
// there was some code before..
reader = new FileReader();
reader.onload = (function (theDiv) {
return function (evt) {
var backgroundimage = "url(" + evt.target.result + ")";
theDiv.css("background-image", backgroundimage);
var sizeSettings = getSizeSettingsFromPage(file, calculateRatio);
};
}(imageDiv));
// step#3 execute file reader
reader.readAsDataURL(file);
// there was some code after..
}
所以每次我预览文件时,我都会尝试对文件的尺寸进行一些计算。
function getSizeSettingsFromPage(file, whenReady) {
reader = new FileReader();
reader.onload = function(evt) {
var image = new Image();
image.onload = function(evt) {
var width = this.width;
var height = this.height;
var filename = file.name;
if (whenReady) {
whenReady(width, height, filename);
}
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
}
function calculateRatio(width, height, filename) {
var ratio = width/height;
var object = new Object();
object['height'] = width;
object['width'] = height;
object['ratio'] = ratio;
object['size'] = 'Original';
for (var size in SIZES) {
var min = SIZES[size].ratio - 0.01;
var max = SIZES[size].ratio + 0.01;
if (ratio <= max && ratio >= min) {
object['size'] = size;
}
}
pageSizes.add(filename, object);
}
在calculateRatio中看到的pageSizes 是一个全局变量,它是一个类似数组的变量类型。
在populatePagesArea被调用之前,它肯定是空的。
情况如下:
我的代码是:
populatePagesArea();
getMajorityPageSize(); // this acts on the supposedly non-empty pageSizes global variable
但是因为我认为没有在所有预览图像上调用calculateRatio,所以当调用getMajorityPageSize时,pageSizes总是空的。
如何确保在调用populatePagesArea之后,只有在所有pages
都经过calculateRatio函数后才会触发getMajorityPageSize?
我相信这是异步回调。但我不知道如何为需要经历异步回调函数(如calculateRatio)的对象数组执行此操作。
答案 0 :(得分:1)
简单的解决方案(我已使用// ***
标记了我的更改:
// ***
var totalPages;
function populatePagesArea() {
// there was some code before the for loop
// ***
totalPages = pages.length;
for (var i=0, l=pages.length; i<l; i++) {
addToPagesArea(pages[i], "");
}
// some code after...
}
function addToPages(file, front) {
// there was some code before..
reader = new FileReader();
reader.onload = (function (theDiv) {
return function (evt) {
var backgroundimage = "url(" + evt.target.result + ")";
theDiv.css("background-image", backgroundimage);
var sizeSettings = getSizeSettingsFromPage(file, calculateRatio);
// *** Check to see if we're done after every load
checkPagesReady();
};
}(imageDiv));
// step#3 execute file reader
reader.readAsDataURL(file);
// there was some code after..
}
// *** Call getMajorityPageSize() here, only after all pages have loaded.
function checkPagesReady() {
if (pageSizes.length >= totalPages)
getMajorityPageSize();
}
如果您稍后要处理更多异步事件,那么更好的解决方案是使用promises重构您的代码。 Promises是一种API,旨在以系统和有组织的方式处理异步编程。如果你要做更多的异步工作,它会让你的生活变得更轻松。有很多免费图书馆支持承诺,其中一个主要参与者是Q.js。