我正在尝试访问我的变量,但它给了我一个空数组。
例:
var data = [];
$.each(files, function (index, file) {
var reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsDataURL(file);
function handleReaderLoad(evt) {
data.push({
name: file.name,
file: evt.target.result
});
}
});
console.log(data)
此时数据是一个空数组。当我把控制台放在 foreach 中时.log它会返回我的数据。如何返回并访问在 foreach 之外填写的数据?
handleReaderLoad
将以异步的方式调用。您可以跟踪文件数量并在文件计数完成后登录onload
var data = [];
var fileCount = files.length;
var currentCount = 0;
$.each(files, function(index, file) {
var reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsDataURL(file);
function handleReaderLoad(evt) {
data.push({
name: file.name,
file: evt.target.result
});
currentCount++;
if (currentCount == fileCount) {
console.log(data);
}
}
});
熟悉FileReader
但很明显,方法readAsDataURL
被称为异步。
不会立即调用 onload
方法,代码流将继续运行,而无需等待触发该方法,因此在到达console.log(data)
点时,尚未填充数据。
JavaScript 是一种单线程语言。这意味着调用长时间运行的进程会阻止所有执行,直到该进程完成。UI 元素无响应,动画暂停,并且应用中的其他代码无法运行。此问题的解决方案是尽可能避免同步执行。
执行此操作的一种方法是稍后执行函数,就像事件处理程序一样,事件处理程序在另一个调用引发事件后调用。回调函数是另一种异步处理,因为它们回调启动进程的代码。
JavaScript 中的异步编程
这可以解决问题。
var data = [];
$.each(files, function (index, file) {
var reader = new FileReader();
reader.onloadend = handleReaderLoad;
reader.readAsDataURL(file);
});
function handleReaderLoad(evt) {
data.push({
name: file.name,
file: evt.target.result
});
if(files.length == data.length)
console.log(data);
}