在HTML5中,有没有办法使Filereader的readAsBinaryString()同步?

5
等待 onload 事件完成的方法
function(){

var filedata=null;     
reader.onload=function(e){
filedata=e.target.result;
};
reader.readAsBinaryString(file);

//I need code to wait till onload event handler gets completed.
return filedata;
}
5个回答

3

通常的解决方法是将代码分开,使用已加载数据的部分放在一个单独的函数中,并从事件中调用该函数。

伪代码如下:

function load() {
    //load here
    reader.onload = function(e) {
        process(e.target.result);
    }
}

function process(result) {
    //finish working here
}

1
我更喜欢直接使用函数,而不是将其封装在匿名函数中,即使用 reader.onload = process 并将 process 函数更改为 process(e),然后从内部处理事件(也许使用 var filedata = e.target.result)。 - syockit

2

1
Jani的回答是正确的,但是在将多个文件同时拖入拖放区域的情况下,每个文件并没有单独的事件(据我所知)。但是可以使用这个想法通过递归同步加载文件。在下面的代码中,我加载了若干个文件,并将它们的内容连接成一个字符串以供进一步处理。
var txt="", files=[];
function FileSelectHandler(e) {
    e.preventDefault();
    files = e.target.files || e.dataTransfer.files;
    txt=""; 
    readFile(0);
}

function readFile(n) {
    file=files[n];
    var reader = new FileReader();
    reader.onload = function() {
        txt += reader.result;
    }
    reader.readAsText(file);
    if (n<files.length-1) { readFile(n+1); }
    else { setTimeout(doWhatEver, 100);}
}

function doWhatEver(){
    outtext.innerHTML=txt; 
}    

最后一个文件也需要额外的时间来加载,因此使用了“setTimeout”函数。
“outtext”是指向文本区域的句柄,整个字符串将在其中显示。在文本区域输出时,浏览器不会解析字符串。这使得可以查看文本以及HTML、XML等内容。

1
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>

<form><input type="file" id="files" name="file" onchange="upload()" /></form>

function readFile(dfd) {
    bytes = [];
    var files = document.getElementById('files').files;
    if (!files.length) {
        alert('Please select a file!');
        return;
    }
    var file = files[0];
    var reader = new FileReader();

    // If we use onloadend, we need to check the readyState.
    reader.onloadend = function(evt) {
        if (evt.target.readyState == FileReader.DONE) { // DONE == 2
            var content = evt.target.result;
            //bytes = stringToBytes(content);
            dfd.resolve(content);
        }
    };
    reader.readAsBinaryString(file);
}

function upload() {
    var dfd = new $.Deferred();
    readFile(dfd);
    dfd.done(function(content){
        alert("content:" + content);
    });
}

0

没有。在Javascript中,所有IO操作都必须是异步的。

将文件操作变成同步操作会有效地阻塞浏览器UI线程,导致浏览器冻结。用户不喜欢这样。

相反,您需要以异步方式设计脚本。使用Javascript非常容易。


此外,如果您需要在文件读取期间阻止用户交互,则可以使用其 onloadstart 来开始阻止(或使用 onprogress 确保仍在阻止),然后在 onloadend 中放置取消阻止的过程。 - syockit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接