2017-10-19 68 views
1

我想在ajax调用中发布对象的javascript数组,但我得到字符串值“[]”。当我尝试console.log数组长度它说零。不能发布对象的javascript数组

以下是代码我使用

var masterFileArray = []; // where I will store the contents 
function readMultipleFiles(evt) { 
//Retrieve all the files from the FileList object 
var files = evt.target.files; 
if (files) { 
    for (var i = 0, f; f = files[i]; i++) { 
     var r = new FileReader(); 
     r.onload = (function (f) { 
      return function (e) { 
       var contents = e.target.result; 
       masterFileArray.push({name:f.name, contents: contents, type:f.type, size:f.size}); // storing as object 

      }; 
     })(f); 
     r.readAsText(f); 
    } 
    console.log(masterFileArray); 
    new Ajax.Request('fileupload.php', { 
    method: 'post', 
    parameters: {files: JSON.stringify(masterFileArray)}, 
    onSuccess: function(transport){ 
     var response = transport.responseText; 
     console.log(response); 
    } 
}); 

} else { 
    alert('Failed to load files'); 
    } 
} 
document.getElementById('upfiles').addEventListener('change', readMultipleFiles, false); 

那怎么看起来像检查

enter image description here

什么,我做错了什么?任何帮助将不胜感激,谢谢。

+2

因为你在'onload'异步功能添加的元素,基本上是这样。 'readAsText'不会阻塞并等待文件被读取,所以你的代码在数组填充之前立即继续发出请求。 –

+0

在文件读取器读取文件之前,您正在执行Ajax请求。 – Danmoreng

+1

r.onload被解雇了吗? Console.log里面知道:) –

回答

1

您可以在阅读完成后发帖, 这里介绍left_loaded_count以获取阅读状态。 像这样尝试。

var masterFileArray = []; // where I will store the contents 
var left_loaded_count = 0; 
function readMultipleFiles(evt) { 
//Retrieve all the files from the FileList object 
var files = evt.target.files; 
if (files) { 
    for (var i = 0, f; f = files[i]; i++) { 
     var r = new FileReader(); 
     r.onload = (function (f) { 
      return function (e) { 
       var contents = e.target.result; 
       masterFileArray.push({name:f.name, contents: contents, type:f.type, size:f.size}); // storing as object 
       left_loaded_count -= 1; 
       if(left_loaded_count == 0) 
       { 
       console.log(masterFileArray); 
       new Ajax.Request('fileupload.php', { 
        method: 'post', 
        parameters: {files: JSON.stringify(masterFileArray)}, 
        onSuccess: function(transport){ 
        var response = transport.responseText; 
        console.log(response); 
        } 
        }); 
       } 
      }; 
     })(f); 
     left_loaded_count += 1; 
     r.readAsText(f); 
    }  
} else { 
    alert('Failed to load files'); 
    } 
} 
document.getElementById('upfiles').addEventListener('change', readMultipleFiles, false); 
1

readAsText()是一个异步操作,但你着手马上而不是等待读取操作完成AJAX调用。这就是为什么你的console.log(masterFileArray)打印一个空数组,当它运行没有完成的操作和数组仍然是空的。

解决此问题的最佳方法是将每个文件读取操作包装在承诺中,然后在所有这些承诺解决后继续进行AJAX调用。
摆脱var masterFileArray = []if (files) { ... }块中的代码改成这样:

Promise.all(files.map(function(f) { 
    return new Promise(function(resolve) { 
     var r = new FileReader(); 
     r.onload = function (e) { 
     var contents = e.target.result; 
     resolve({name:f.name, contents: contents, type:f.type, size:f.size}); // resolve promise with object 
     }; 
     r.readAsText(f); 
    }); 
    })).then(function(masterFileArray) { 
    // All promises have resolved and their results have been collected in masterFileArray 
    console.log(masterFileArray); 
    new Ajax.Request('fileupload.php', { 
     method: 'post', 
     parameters: {files: JSON.stringify(masterFileArray)}, 
     onSuccess: function(transport){ 
     var response = transport.responseText; 
     console.log(response); 
     } 
    ); 
    });