在for循环中等待承诺

时间:2013-12-28 10:04:20

标签: javascript jquery pdf.js

进入这整个异步的东西我有点麻烦。我正在使用pdf.js来读取pdf文件的内容。一切正常,但执行顺序给我带来了麻烦。这是我的代码:

function getText(data) {
    var contents = [];
    PDFJS.getDocument(data).then(function(pdf) {
        var numPages = pdf.pdfInfo.numPages;
        for (var i = 1; i <= numPages; i++) {
            pdf.getPage(i).then(function(page) {
                page.getTextContent().then(function(content) {
                    contents.concat(content.bidiTexts);
                })
            });
        }
    })
}

这是按预期工作的,但是,我希望在处理完所有页面并将其bidiTexts连接到内容时传递contents。如果我只是在最后一次结束contents之前使用}作为参数进行函数调用,那么它会被提前调用。

2 个答案:

答案 0 :(得分:1)

尝试使用承诺:

function getText(data) {
    var contents = [];
    var promises = [];

    PDFJS.getDocument(data).then(function(pdf) {
        var numPages = pdf.pdfInfo.numPages;

        for (var i = 1; i <= numPages; i++) {
            var deferred = $.Deferred(); //Create a deferred object
            promises.push(deferred.promise()); //push promise to the list

            pdf.getPage(i).then(function(page) {
                page.getTextContent().then(function(content) {
                    contents.concat(content.bidiTexts);
                    deferred.resolve(); //resolve the deferred object
                })
            });
        }

        $.when.apply($,promises).then(function(){ //callback executed when all deferreds are resolved
            //do your task with contents
        });
    })
}

这只是一个如何使用promises的演示。在实际应用程序中,您必须使用deferred.reject处理错误,并在第二次回调$.when

中处理错误

答案 1 :(得分:-1)

您可以使用async/await

async function getText(data) {
    var contents = [];
    var pdf = await PDFJS.getDocument(data);

    var numPages = pdf.pdfInfo.numPages;

    for (var i = 1; i <= numPages; i++) {
      var page = await pdf.getPage(i);
      var content = await page.getTextContent();

      contents.concat(content.bidiTexts);      
    }    
}

请注意,getText将返回一个承诺,您可以再次使用async /await访问结果或getText(data).then(result => console.log(result));

如果要并行获取页面,请使用Promise.All然后将await用作.getContent()

async function getText(data) {
  var pdf = await PDFJS.getDocument(data)
  var numPages = pdf.pdfInfo.numPages;

  var promises = [];

  for (var i = 1; i <= numPages; i++) {
    promises.push(pdf.getPage(i));
  }

  var result = await Promise.All(promises)
    .then(pages => pages.map(page => await page.getTextContent()));

  return result;
}