おそらく複数の非同期コールバックの状況を含むもつれに陥りました。
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 が呼び出された後、すべての calculateRatio 関数が実行された後にのみ getMajorityPageSize がトリガーされるようにするにはどうすればよいpages
ですか?
これは非同期コールバックだと思います。しかし、calculateRatio のような非同期コールバック関数を実行する必要があるオブジェクトの配列に対してそれを行う方法がわかりません。