如何将 js filereader 结果保存到变量中以供进一步使用?
How do i save the js filereader result into a variable for futher use?
我正在尝试将本地 .json 文件上传到我的网络应用程序中。我已经到了可以在开发工具中显示该文件的地步,但我无法使其可供进一步使用。我怀疑问题出在我处理(或不处理)文件 reader.
的异步行为的方式上
整个过程都在 Angularjs (1.7) 环境中运行,因此是该片段的语法。预期用途是在 openlayers 地图上显示读取的数据。
this.jsonSelected = function(newFile) {
let reader = new FileReader();
let result = 'empty';
reader.readAsText(newFile);
reader.onload = function(e) {
result = e.target.result;
console.log('in onload', result);
this.result = e.target.result;
};
console.log(this.result);
};
this.test = function() {
console.log(this.file);
}
我希望代码两次注销文件内容。一次在 "console.log ('in onload', result);" 上,另一次在 "console.log (this. result);" 上。第一个按预期工作。但出于某种原因,第二个不会。控制台中的顺序也被翻转,console.log(this.result)出现在 inload 日志之前,如您在此 screenshot of the console.
中所见
我尝试了几种变体,翻转名称,更改 this。等等,但无济于事。这就是为什么我认为我搞砸了异步数据的处理。此外,屏幕截图,更具体地说是日志中的线条,表明存在某种计时问题。
这是典型的异步 + 范围问题...
首先你用错了范围。
reader.onload
中的 this
与 console.log(this.result);
中的 this
不同。
您应该 bind
onload
或使用箭头函数。
接下来,onload
是异步的,因此它将 运行 在 console.log(this.result);
之后。
处理此问题的一种方法是使用 Promises(AngularJS 中的 $q
)。
类似于:
const deferred = $q.defer();
deferred.then((data) => { console.log('result', data); });
reader.onload = function(e) {
result = e.target.result;
console.log('in onload', result);
deferred.promise.resolve(e.target.result);
};
经过进一步研究和反复试验后,我找到了解决方案。代码现在看起来像这样:
function readFile(newFile) {
return $q(function(resolve, reject) {
let reader = new FileReader();
reader.onload = function(event) {
resolve(event.target.result);
};
reader.onerror = function(event) {
reject(event);
};
reader.readAsText(newFile);
});
}
this.jsonSelected = function(newFile) {
readFile(newFile).then(function(data) {
console.log(data);
set$scopeFile(data);
}, function(errData) {
});
};
谢谢 Ben,你让我走上了正轨,我太专注于寻找处理异步部分的方法,而忽略了范围问题。如果有人有一些关于异步 JS 的 "fool proof" 文档,我将不胜感激,因为我无法围绕这个主题展开思考。
我已经使用 angularjs' 内置的 $q 服务将整个读取过程包装到 promise 中。然后可以用 .then
.
链接
我正在尝试将本地 .json 文件上传到我的网络应用程序中。我已经到了可以在开发工具中显示该文件的地步,但我无法使其可供进一步使用。我怀疑问题出在我处理(或不处理)文件 reader.
的异步行为的方式上整个过程都在 Angularjs (1.7) 环境中运行,因此是该片段的语法。预期用途是在 openlayers 地图上显示读取的数据。
this.jsonSelected = function(newFile) {
let reader = new FileReader();
let result = 'empty';
reader.readAsText(newFile);
reader.onload = function(e) {
result = e.target.result;
console.log('in onload', result);
this.result = e.target.result;
};
console.log(this.result);
};
this.test = function() {
console.log(this.file);
}
我希望代码两次注销文件内容。一次在 "console.log ('in onload', result);" 上,另一次在 "console.log (this. result);" 上。第一个按预期工作。但出于某种原因,第二个不会。控制台中的顺序也被翻转,console.log(this.result)出现在 inload 日志之前,如您在此 screenshot of the console.
中所见我尝试了几种变体,翻转名称,更改 this。等等,但无济于事。这就是为什么我认为我搞砸了异步数据的处理。此外,屏幕截图,更具体地说是日志中的线条,表明存在某种计时问题。
这是典型的异步 + 范围问题...
首先你用错了范围。
reader.onload
中的 this
与 console.log(this.result);
中的 this
不同。
您应该 bind
onload
或使用箭头函数。
接下来,onload
是异步的,因此它将 运行 在 console.log(this.result);
之后。
处理此问题的一种方法是使用 Promises(AngularJS 中的 $q
)。
类似于:
const deferred = $q.defer();
deferred.then((data) => { console.log('result', data); });
reader.onload = function(e) {
result = e.target.result;
console.log('in onload', result);
deferred.promise.resolve(e.target.result);
};
经过进一步研究和反复试验后,我找到了解决方案。代码现在看起来像这样:
function readFile(newFile) {
return $q(function(resolve, reject) {
let reader = new FileReader();
reader.onload = function(event) {
resolve(event.target.result);
};
reader.onerror = function(event) {
reject(event);
};
reader.readAsText(newFile);
});
}
this.jsonSelected = function(newFile) {
readFile(newFile).then(function(data) {
console.log(data);
set$scopeFile(data);
}, function(errData) {
});
};
谢谢 Ben,你让我走上了正轨,我太专注于寻找处理异步部分的方法,而忽略了范围问题。如果有人有一些关于异步 JS 的 "fool proof" 文档,我将不胜感激,因为我无法围绕这个主题展开思考。
我已经使用 angularjs' 内置的 $q 服务将整个读取过程包装到 promise 中。然后可以用 .then
.