1

我让自己陷入了一个可能涉及多个异步回调情况的纠结中。

我有一个名为 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 后,getMajorityPageSize 仅在所有pages都经历了 calculateRatio 函数后才被触发?

我相信这是异步回调。但是我不确定如何为需要经历像calculateRatio这样的异步回调函数的对象数组执行此操作。

4

1 回答 1

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,旨在以系统和有组织的方式处理异步编程。如果你要做更多的异步工作,它会让你的生活更轻松。有很多支持 Promise 的免费库,主要参与者之一是Q.js。

于 2012-11-27T13:16:59.700 回答