2013-06-12 53 views
19

我想讀取一個文件並使用FileReader對象將其轉換爲base64編碼的字符串。下面是我使用的代碼:以Javascript同步讀取文件

 

    var reader = new FileReader(); 
    reader.onloadend = function(evt) { 
     // file is loaded 
     result_base64 = evt.target.result; 
    }; 
    reader.readAsDataURL(file); 


但在這種情況下,我得到的事件處理程序(onLoadEnd事件)轉換的結果。我想要一個同步方法。有沒有辦法「readAsDataURL」方法可以直接返回'result_base64'變量的值?

謝謝

+3

*「我想要一個同步方法。」*有什麼特別的原因?我不認爲這是可能的。 –

+0

firefox擁有/擁有file.getAsDataURL()方法,但它已被棄用,並且是任何瀏覽器afaik的唯一同步版本。 – dandavis

+0

我將路徑存儲在本地存儲數據庫中,之後需要將圖像發送到服務器(在所有圖像上使用循環,這就是爲什麼我需要同步方法)。 我想避免在數據庫中存儲base64字符串,以便不超過本地存儲限制... – Laila

回答

10

同步任務(阻塞)通常是不好的。如果沒有真正的理由異步執行此操作,我強烈建議您使用事件回調。

想象一下你的文件壞了,HTML5 API不能讀取,它不會給你結果。它會破壞你的代碼並阻止網站。或者,有人可能會選擇一個10GB文件,這會凍結您的HTML頁面,直到文件完全加載。使用該異步事件處理程序,您可以捕獲可能的錯誤。

要解決侷限性回調,我用一個簡單的一招:

var ready = false; 
var result = ''; 

var check = function() { 
    if (ready === true) { 
     // do what you want with the result variable 
     return; 
    } 
    setTimeout(check, 1000); 
} 

check(); 

var reader = new FileReader(); 
reader.onloadend = function(evt) { 
    // file is loaded 
    result = evt.target.result; 

    ready = true; 
}; 
reader.readAsDataURL(file); 

的檢查功能,檢查每一秒,如果準備好標誌變量設置爲true。如果是這樣,你可以確定結果是可用的。

這可能不是最好的做法,但我做了一個webapp使用這個技術約30次,超過10個setTimeouts在同一時間運行,直到現在沒有遇到任何問題。

+0

我曾經有過類似的伎倆,但是一旦我將代碼插入到循環中就會破壞它。我最終使用了與閉包結合的回調方法來知道循環何時結束。 – Laila

+1

有我想要傳遞參數變量回調的完全相同的問題。目的是將文件分成塊,所以我可以將它大塊發送到服務器。一旦隱藏起來,關閉是一件好事。 –

+0

https://stackoverflow.com/a/46832928/851951這種方法很好,但它仍然是異步工作的。 – Dani

-3

業務遲到,但可能會有助於某人。我們可以簡單地在房間外面打架。

var file = $('#myfile')[0].files[0]; 

var reader = new FileReader(); 
reader.onload = function(progressEvent) { 
     //console.log(this.result); 
     handle(this.result); 
}; 
reader.readAsText(file); 

function handle(temp_lines) { 
    var inputLines=new Array(); 
    var lines = temp_lines.split('\n'); 

    for(var line = 0; line < lines.length; line++) { 
     console.log(lines[line]); 
     inputLines[line]=lines[line]; 
    } 
} 
+4

我不清楚這是如何同步的。 – Nathan

+0

不是。這是一個異步的方式。 – trinalbadger587

0

在Node.js的,使用execSyncchild_process和有殼讀它爲你同步。將此子進程的輸出重定向到父進程。

// Don't forget to use your favorite encoding in toString() 
var execSync = require('child_process').execSync; 
var fileContents = execSync('cat path/to/file.txt', {stdio: "pipe"}).toString(); 

我很樂意接受你提名的UUOC獎。 ;)