我正在尝试将本地.json文件上传到我的Web应用程序中。我已经到了可以在开发工具中显示文件的地步,但是我无法使其可供进一步使用。我怀疑问题出在我处理(或不处理)文件读取器的异步行为的方式上。
整个事情都可以在Angularjs(1.7)环境中进行,因此代码段的语法也是如此。预期用途是在开放图层地图上显示读入的数据。
False
我希望代码两次注销文件内容。进入“ console.log('in onload',结果)“;另一个时间在“ console.log(此结果);”上。第一个按预期工作。但由于某种原因,第二个不会。此外,控制台中的顺序也被翻转,console.log(此结果)位于加载日志之前,如您在此screenshot of the console中所见。
我尝试了几种变体,翻转名称,更改名称。依此类推,但无济于事。这就是为什么我认为自己搞砸了异步数据的处理。屏幕截图,更具体地说是日志中的线路,也表明存在某种时序问题。
答案 0 :(得分:1)
经过进一步的研究和反复试验,我得出了一些解决方案。现在的代码如下所示:
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有一些“万无一失”的文档,我将不胜感激,因为我在解决这个话题时遇到了麻烦。
我已经使用angularjs内置的$ q服务将整个阅读过程包装为promise。然后可以与.then
链接。
答案 1 :(得分:0)
这是经典的异步+作用域问题...
首先,您使用了错误的范围。
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);
};