Я попал в путаницу, которая, вероятно, связана с несколькими асинхронными ситуациями обратного вызова.несколько асинхронных обратных вызовов javascript, как это разрешить?
У меня есть яваскрипта функция называется populatePageArea()
Внутри populatePageArea он проходит через этот массив типа переменные, называемые страницы среди другого кода.
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 я использовал FileAPI из HTML 5 для предварительного просмотра Drag'n упал файлов среди другого кода.
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);
}
pageSizes, как показано на calculateRatio представляет собой глобальную переменную, которая представляет собой массив-подобный тип переменной.
Он определенно пуст ПЕРЕД НАПОЛНЕНИЕМ.
Вот ситуация:
мой код:
populatePagesArea();
getMajorityPageSize(); // this acts on the supposedly non-empty pageSizes global variable
Но потому, что я думаю, что calculateRatio не был вызван на ВСЕХ просматриваемо изображений, то pageSizes всегда пусто, когда getMajorityPageSize называется.
Как я могу убедиться, что после вызова populatePagesArea getMajorityPageSize запускается ТОЛЬКО после того, как все pages
прошли функцию calculateRatio?
Я считаю, что это асинхронный обратный вызов. Но я не уверен, как это сделать для массива объектов, которые должны будут обработать функцию async callback, например calculateRatio.
Привет, Натан, спасибо! Я сделал только одно изменение кода. Я переместил вызов checkpagesready на последнюю строку calculateRatio. –
, кстати, я столкнулся с этим https://github.com/caolan/async#series по сравнению с обещаниями, какой из них ... более перспективным? Хех, каламбур. –
Если вы собираетесь много работать с Node, библиотека Async, с которой вы связаны, может быть очень полезна, потому что она более тесно связана с соглашениями узла. Тем не менее, я думаю, что обещания - более надежное и мощное решение, и были предприняты некоторые попытки переместить узел в этом направлении. Кроме того, есть много дискуссий о [добавлении обещаний к будущей версии ECMAScript] (http://wiki.ecmascript.org/doku.php?id=strawman:concurrency).Поэтому я определенно думаю, что они заслуживают изучения. –