【问题标题】:Why can't the array elements be accessed? (javascript) [duplicate]为什么不能访问数组元素? (javascript)[重复]
【发布时间】:2016-06-17 03:38:43
【问题描述】:

由于某种原因,当元素被推送到 FileReader.onload 事件函数中的数组时,该数组的元素稍后将无法访问。考虑以下代码:

scope.targets = [];

for(var i = 0; i < files.length; i++){
        var reader = new FileReader();
        reader.readAsDataURL(files[i]);

        reader.onload = function(e){
              scope.targets.push(e.target.result);
        };
 }

 console.log(scope.targets);
 console.log(scope.targets[0]);

这是 Google Chrome 浏览器中 console.log() 输出的结果。 正如您所看到的,scope.targets 显示有一个字符串类型的元素。 但是,scope.targets[0] 是未定义的。为什么会这样?还有其他方法可以访问该元素吗?


******************************更新************************ *****************


这里有一个解决方案。谢谢 Ashwin Balamohan 和 nnnnn 的回答,这让我找到了解决方案。我在这里找到了我想要的东西How to implement Progress Bar and Callbacks with async nature of the FileReader

解决办法是:

scope.targets = [];

for(var i = 0; i < files.length; i++){
        var reader = new FileReader();
        reader.readAsDataURL(files[i]);

        reader.onload = function(e){
              scope.targets.push(e.target.result);
              if(i == files.length){
                    callback();
              }
        };
 }

 var callback = function(){
     console.log("scope.targets:");
     console.log(scope.targets);
     console.log("scope.targets[0]:");
     console.log(scope.targets[0]);
 }

【问题讨论】:

  • 由于您请求的性质,我们无法轻易复制此内容。你最好做一个 jsFiddle 或者我们可以用来查看问题的东西。
  • 数组填充在异步运行的函数中,console.log() 语句在此之前运行。根据您使用的浏览器,控制台可能会保留对已记录对象的引用,这样当您在控制台中展开数组时,即使在记录时它是空的,它也确实有值。试着在同一点说console.log(JSON.stringify(scope.targets)),看看会发生什么。

标签: javascript arrays angularjs filereader


【解决方案1】:

你可以试试这个

scope.targets = {};

for(var i = 0; i < files.length; i++){
        var reader = new FileReader();
        reader.readAsDataURL(files[i]);

        reader.onload = function(e){
              scope.targets[i] = (e.target.result);
        };
 }

console.log(scope.targets);
console.log(scope.targets[0]);

【讨论】:

  • 为什么会有任何不同?
【解决方案2】:

代码正在异步执行。见下面的cmets

scope.targets = [];

for(var i = 0; i < files.length; i++){
        var reader = new FileReader();
        reader.readAsDataURL(files[i]);

        // below is an asynchronous call
        reader.onload = function(e){
              scope.targets.push(e.target.result);
        };
 }

 // the asynchronous calls above may or may not be complete by the time you get here
 console.log(scope.targets);
 console.log(scope.targets[0]);

您可以做的是修改您的reader.onload 函数,使其在回调中执行console.log

scope.targets = [];

for(var i = 0; i < files.length; i++){
        var reader = new FileReader();
        reader.readAsDataURL(files[i]);

        // below is an asynchronous call
        reader.onload = function(e){
              scope.targets.push(e.target.result);
              // log out the array here, instead
              console.log(scope.targets);
        };
 }

【讨论】:

  • 是的,将 console.log(scope.targets) 放在 reader.onload 函数中有效。但是,我需要 reader.onload 函数之外的 scope.targets 数组数据。
  • 你的答案是正确的。不过我希望有一个解决方案。
  • 太好了,@Ellioticus。我很高兴最终能够提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 2018-01-06
相关资源
最近更新 更多