2016-11-17 70 views
-3

我對如何使用承諾略有困惑。我已經閱讀了一些關於承諾的內容,主要是因爲它好像我必須使用它們。我正在研究一個小應用程序,它應該使用pdfjs搜索一些pdf文件,並使用promise。通過查看網絡上的各種示例,我在nodejs中敲了一些東西,但遇到了一個問題。javascript的承諾,在這裏需要嗎?

讓我們看一下代碼第一:

require('pdfjs-dist'); 
var fs = require('fs'); 

//var searchTerm = "course"; 
var searchTerm = "designee"; 
//var searchTerm = "document"; 
var wordCounter = 0; 
var searchResultJSON = []; 
//var data = new Uint8Array(fs.readFileSync('testPdf.pdf')); 
//var data = new Uint8Array(fs.readFileSync('advanced-javascript.pdf')); 
var data = new Uint8Array(fs.readFileSync('iss4.pdf')); 
PDFJS.getDocument(data).then(function (pdfDocument) { 
    console.log('Number of pages: ' + pdfDocument.numPages); 
    //var div = document.getElementById('viewer'); 
    for(var i = 1; i<=pdfDocument.numPages; i++){//loops thru pages 
     console.log("i is " + (i)); 
     pdfDocument.getPage((i)).then(function(page){//get page(i), 
     // console.log("page is " + (i)); 
      //console.log("inside getPage()"); 
      page.getTextContent().then(function(textContent){//get content of pdf 
      //console.log("inside getTextContent()"); 
      //if(null != textContent.items){ 
       var page_text = ""; 
       var last_block = null; 
       var lineWithResult = ""; 

       for(var k = 0; k < textContent.items.length; k++){ 
        var block = textContent.items[k]; 
        //console.log("word " + textContent.items.length + " k is " + k); 
        /* if(last_block != null && last_block.str[last_block.str.length-1] != ' '){ 
         if(block.x < last_block.x) 
          page_text += "\r\n"; 
         else if (last_block.y != block.y && (last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null)) 
          page_text += ' '; 
        } */ 

        page_text += block.str; 

        last_block = block; 
        lineWithResult = searchPdf(block.str); 
        if(lineWithResult != null){ 
         console.log(lineWithResult + " wordCounter is " + wordCounter); 

        } 

       }//end of for(var k...) 
        //console.log(" page_text " + page_text); 
        //console.log(searchResultJSON); 

      //} 
      });//end of textContent.items 

     });//end of getPage 

    }//end of loop  
}); 
function searchPdf(toSearch){//searching pdf for searchTerm 
    var result = toSearch.toLowerCase().indexOf(searchTerm); 
    if(result >=0){//if match is found 
     wordCounter++; 
     //console.log("toSearch " + toSearch + " result is " + result + " wordCounter " + wordCounter); 
     constructResult(toSearch, result);//build the result object 
     return toSearch; 
    } 
    else{//if match not found 
     return null; 
    } 

} 
function constructResult(toSearch, result){//construct array of objects containing: search term, search result and index of search term 
    searchResultJSON.push({ 
     "TextLine":toSearch, 
     "SearchTerm":searchTerm, 
     "Result": result,    
    });  
} 

這段代碼的目的是:

  • 遍歷PDF格式的網頁

  • 遍歷內容

  • 以可變的方式逐行獲取pdf文本

  • 搜索PDF內容與關鍵字

  • 如果關鍵字找到匹配,打印匹配

  • 獲得比賽的JavaScript物件

所以,這一切工作好,但你會注意到,從第二個for循環(我得到的文本是pdf的文本)我調用一個函數,searchPdf()基本上執行搜索,並從該函數內調用另一個函數這應該是創建JavaScript對象與結果的constructResult(...)

雖然我在打印這個對象時遇到了一些問題,因爲如果我將它打印在for循環的範圍之外,它是空的,因爲打印調用(在我的情況下是console.log)在循環實際複製之前執行,分析(讀取過程並找到匹配)的文本。所以,承諾看到了解決問題的方法。事情是,我不知道如何編碼這種方式,以便我可以鏈接承諾並在執行完所有內容後打印我的對象。任何想法?

編輯: 所以要澄清,我需要的順序是這樣的: 1)通過PDF環路(我將不得不通過PDF文件的集合在某一點很快修改代碼迴路) 2)得到各文字 3)的線檢查有匹配 4)如果是這樣,複製文本的行JavaScript對象 5)打印的JavaScript對象

+0

可能[用promise替換回調的副本在Node.js](http://stackoverflow.com/questions/28432401/replacing-callbacks-with-promises-in-node-js) –

+0

你可以創建一個打印函數,從循環內部調用並返回結果到循環外的變量 –

+0

@DexDave,已經嘗試過了,它不起作用,因爲變量將是空的,我需要首先執行所有操作,然後將結果返回給該變量 – antobbo

回答

1

嘗試是這樣的:

function search(doc, s) { 
    var allPages = [], 
     i; 

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

    // Promise.all returns a promise that resolves once 
    // each promise inside allPages has been resolved 
    return Promise.all(allPages) 
    // pages now contains an array of pages, loop over them 
    // using map, return the promise to get the content for each page 
    // return it through Promise.all so we can run the next phase 
    // once the text is resolved for each page 
    .then(pages => Promise.all(pages.map(p => p.getTextContent()))) 
    // We now have an array of contents for each page, filter based 
    // on the passed string 
    .then(content => content.filter(c => c.indexOf(s) > -1)); 
} 

// This is a mock of the pdf API used in your question 
var pdfDocument = { 
    numPages: 3, 
    getPage: function(i) { 
     return Promise.resolve({ 
      getTextContent: function() { 
       return Promise.resolve('Page ' + i); 
      } 
     }); 
    } 
} 
+1

即使代碼正常工作,OP要求解釋。如果你解釋發生了什麼,我認爲這會很有用。 – Marcs

+0

可能要解釋** pdfDocument **這裏是OP的版本的模擬。稍微解釋一下也許是一個好主意。 – JonSG

+0

儘管'Promise.all'將成爲解決方案的一部分,但這個答案並非Promise的最佳使用。根本沒有必要使用'Promise',也沒有必要使用Promise.resolve' –