2016-11-08 5 views
1

Я пытаюсь реализовать число слов в формате PDF в Javascript. Я столкнулся с pdf.js, который использует обещания. Есть ли способ подождать, пока скрипт будет выполнен, прежде чем возвращать счет? Я знаю, что это противоречит идее обещаний, но другие читатели js pdf там либо производят кучу тарабарщины, либо ничего не возвращают. В своем нынешнем виде функция всегда возвращает количество слов 0.Сложности с pdf.js обещает

function countWords(pdfUrl){ 
var pdf = PDFJS.getDocument(pdfUrl); 
var count = 0; 
pdf.then(function(pdf) { 
    var maxPages = pdf.pdfInfo.numPages; 
    for (var j = 1; j <= maxPages; j++) { 
     var page = pdf.getPage(j); 

     var txt = ""; 
     page.then(function(page) { 
      var textContent = page.getTextContent(); 
      textContent.then(function(page){ 

      for(var i=0;i<page.items.length;i++){ 
       txtadd = page.items[i].str 
       txt += txtadd.replace(/[^a-zA-Z0-9:;,.?!-() ]/g,''); 
      } 
       count = count + txt.split(" ").length; 

      }) 
     }) 
    } 
    return count; 
}); 

}

+0

Вам нужно инвертировать поток т.е. логики, в котором нуждается 'count' должен быть в«то», который следует этот счетчик расчет. – Vasan

+0

Как мне это сделать? Я делаю этот метод в объекте и называю его «потом»? Это какой-то код, который я получил от Spring.io, это то, что вы имеете в виду? var приветствиеPromise = sayHello(); приветствиеPromise.then (функция (приветствие) { console.log (приветствие); // 'hello world' }); –

+0

Что-то в этом роде. В принципе, ваш метод подсчета возвращает Promise (вместо самого счета) с разрешенным счетчиком ('resolve (count)'). Затем вы добавляете блок .then к этому возвращенному обещанию и делаете что-то со счетом внутри блока. – Vasan

ответ

3

Обещания не могут быть обработаны в синхронизации способом. CountWords не может вернуть значение немедленно и должен ждать внутренних обещаний (один для документа и несколько для страниц и контекстов текста), которые должны быть разрешены. Поэтому countWords должен вернуть Promise или принять обратный вызов. Лучший способ - попытаться вернуть и вызвать цепочку() вызовов. При необходимости присоединиться использовать разрешение Promise.all:

function countWords(pdfUrl){ 
 
var pdf = PDFJS.getDocument(pdfUrl); 
 
return pdf.then(function(pdf) { // calculate total count for document 
 
    var maxPages = pdf.pdfInfo.numPages; 
 
    var countPromises = []; // collecting all page promises 
 
    for (var j = 1; j <= maxPages; j++) { 
 
     var page = pdf.getPage(j); 
 

 
     var txt = ""; 
 
     countPromises.push(page.then(function(page) { // add page promise 
 
      var textContent = page.getTextContent(); 
 
      return textContent.then(function(page){ // return content promise 
 

 
      for(var i=0;i<page.items.length;i++){ 
 
       txtadd = page.items[i].str 
 
       txt += txtadd.replace(/[^a-zA-Z0-9:;,.?!-() ]/g,''); 
 
      } 
 
       return txt.split(" ").length; // value for page words 
 

 
      }); 
 
     })); 
 
    } 
 
    // Wait for all pages and sum counts 
 
    return Promise.all(countPromises).then(function (counts) { 
 
     var count = 0; 
 
     counts.forEach(function (c) { count += c; }); 
 
     return count; 
 
    }); 
 
}); 
 
} 
 
// waiting on countWords to finish completion, or error 
 
countWords("https://cdn.mozilla.net/pdfjs/tracemonkey.pdf").then(function (count) { 
 
    alert(count); 
 
}, function (reason) { 
 
    console.error(reason); 
 
});
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>

+0

P.S. это не имеет никакого отношения к PDF.js - так работает ECMAScript Promises – async5

+0

Я знаю, что это было год назад, но вы не представляете, насколько этот ответ помог мне выполнить аналогичную задачу с PDF.js. Благодаря! –