我正在尝试将本地.json文件上传到我的Web应用程序中。我已经到了可以在开发工具中显示文件的地步,但我无法将其用于进一步使用。我怀疑问题在于我处理(或不处理)文件阅读器的异步行为。
整个事情在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('inload',结果);”还有一次在“console.log(this.rend result);”上。第一个按预期工作。但出于某种原因,第二个不会。同样,控制台中的顺序也会被翻转,console.log(这个。结果)出现在inload日志之前,你可以在这个screenshot of the console中看到。
我尝试了几种变化,翻转名称,改变这一点。等等,但无济于事。这就是为什么我认为我搞乱了异步数据的处理。此外,屏幕截图,更具体地说是日志中的linies,表明存在某种时序问题。
经过一些进一步的研究和一些反复试验后,我得到了解决方案。代码现在看起来像这样:
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上有一些“万无一失”的文档,我会非常感激,因为我无法绕过这个主题。
我使用了$ q服务中内置的angularjs来将整个阅读过程包装到promise中。然后可以与.then
链接。
这是一个经典的异步+范围问题......
首先使用错误的范围。 this
内部的reader.onload
与this
中的console.log(this.result);
不同。
你应该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);
};