【问题标题】:Read and copy file data with FileReader使用 FileReader 读取和复制文件数据
【发布时间】:2014-04-04 05:12:33
【问题描述】:

我正在尝试通过 FileReader 从客户端读取文件。我想在浏览器中创建一个副本,但我不知道如何正确地做到这一点。 在这个JSFiddle 中,我复制了我的问题,但我使用自定义类File 而不是Object,但结果相同。

如果我只选择一个文件,一切都很好,但是一旦我选择多个文件,就会出现错误。首先,我在line 9 上创建的新对象的所有属性(data 除外)始终是最后选择的文件。函数storeResult 从fileReader 获取结果OK,但不是从我的新Object 文件?

当我单击“检查数组”时,数组属性 data 中的所有对象现在是最后一个选择的文件。我的猜测是它与我的一些变量的范围有关,但我不知道在哪里以及为什么。

【问题讨论】:

  • 您不会为循环的每一轮捕获file 的当前值,因此每个函数最终只存储 last 值。 Here's a fixed fiddle(我唯一改变的是添加对当前文件的显式引用作为您的 IIFE 的参数(function(file) { /* your code */ }(file));
  • 谢谢,这行得通!我以前从未听说过 IIFE。这种行为是 Javascript 特有的吗?我怎么知道什么时候应该使用这种方法?另外,将您的评论作为答案,我会接受。 @SeanVieira

标签: javascript filereader


【解决方案1】:

你有一个mutating reference bug:

var files = evt.target.files, i, f; 
for (i = 0; f = files[i]; i++) {
    var reader = new FileReader()
    reader.onload = function onLoad(event) {
        // f is available here
        // but it is not a fixed reference.
        // It changes each time the body
        // of the loop is executed.
        // This function (regardless of the current value of `i`)
        // will only be executed after the containing `for` loop
        // has run to completion.
    };

    // Schedule some work for later
    reader.readAsDataURL(f);
}

最简单的解决方法是将当前f 的引用存储在闭包中:

reader.onload = (function createHandler(currentFile) {
  return function onLoad(event) {
    // f is available here
    // but it is not a fixed reference.

    // `currentFile` is pointing at the value for `f`
    // as it is for this iteration of the loop
    // (that is, it is a fixed reference).
  };

// In order to preserve the state of `f`
// we create a new reference to the value that `f` points
// to for this new function closure and bind it to `currentFile`
// by passing in `f` to our createHandler Immediately Invoked Function Expression
}(f));

如果我们重构出工厂函数,我们在做什么就会变得更加清晰:

// As a "top-level" function
function createHandler(currentFile) {
  return function onLoad(event) {
    // f is *not* available here.
    // `currentFile` is a reference to the value of
    // whatever is passed in to our `createHandler` function.
    // (that is, it is a fixed reference).
  };
}

// Then, in our handler:
reader.onload = createHandler(f);

【讨论】:

    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 2019-07-04
    • 2023-04-07
    • 2017-12-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多