Javascript FileReader:提取文本

Javascript FileReader: Extracting text

我无法保存从 FileReader 读取的文件中提取的数据。

onload 函数的范围内数据似乎存在,但试图将所述数据存储在范围外的变量中似乎不起作用。

MWE: http://jsfiddle.net/eqaw0hbf/1/

(上传任何文本文件,您就会明白我的意思)

我倾向于说 onload 函数是异步的。换句话说,它会在加载结束时触发并仅执行 "function(e){}" 作用域(因此得名 "onloadend")。同时, "function(e){}" 范围之外的程序的其余部分将在等待加载结束时继续执行。这并不是说数据没有存储在文本变量中。只是第 14 行 "alert(text)" 调用发生在 "function(e){}" 作用域有机会将 'text' 变量设置为非空值之前。

您的代码将开始并执行第 2-3 行,然后跳转到第 10 行(并打印 alert(text),它只是 "",因为函数 (e) 从未执行过,因此 text 从未设置为任何事物)。当 "lr.onloadend" 的服务器或请求最终收到其数据时,您的程序将跳回到第 6 行并执行 lr.onloadend = function(e){} 内的范围并设置文本变量。

您应该做的是将任何依赖于文本的数据处理放在 onload 的回调中,在此范围内:lr.onloadend = function(e){}。基本上只要你有一个异步函数,内部发生的任何事情都应该假定发生在任何更高范围内的所有代码之后。不在 "callback" 函数内的任何内容都将按照您期望的顺序正常执行。回调函数内的任何事情都只有在回调被触发时才会发生。所以你不能让回调函数外的事情依赖于回调函数内发生的事情。无法保证在异步回调中设置的信息可以 'trigger' 无论何时都可以在其他任何地方使用。

这篇 link 很好地解释了 Node 中的回调。js/Javascript:

http://cwbuecheler.com/web/tutorials/2013/javascript-callbacks/

那是因为它 运行 或多或少是异步的。系统正在等待事件 onloadend,然后设置文本变量。

您可以通过在上次提醒之前进行某种延迟来观察这种情况的发生。

function DoData(file) {                
    var lr = new FileReader();
    var text = "";

    lr.onloadend = function(e){
        text = e.target.result;
    };
    lr.readAsText(file);
    // this will display the correct result, after a delay of 1 second
    setTimeout(function() {alert(text)}, 1000);
    // this will display a blank string, 
    // because the text hasn't been loaded yet
    alert(text);
}

通常情况下,您要做的是在onloadend事件中添加对text变量的处理函数。那是唯一一次您确实知道文本变量已正确初始化。

    lr.onloadend = function(e){
        text = e.target.result;
        functionToProcessText(text);
    };