我有一个包含我想要阅读的JSON数据的文件。我在neontribe.co.uk找到了一些读取文件的代码,但我似乎无法让控制台等待负载完成。
-Xlint:private-shadow
当我运行它时,我在控制台中得到了这个输出:
在function1内部 数据!未定义 数据字符串!未定义 1452034357845.json 内部加载[对象对象]
所以它看起来像some_function然后打印内部函数1.但是它不等待函数从加载传递结果。它会立即从回调函数中打印出两行。然后打印文件名(在循环结束时),然后最终从加载函数中打印控制台消息。看起来我根据控制台返回一个对象,因此数据不应该是未定义的。
答案 0 :(得分:3)
代码有一些错误,主要是因为它没有考虑异步调用而只是假设一切都以同步方式发生。
callback(data)
中的some_function(callback)
实际上是在您致电var data = readFromFile(entries[i].name);
后调用的。但这里出现了两个问题。
function readFromFile(fileName)
不返回任何数据(实际上,它根本不返回任何内容); reader.readAsText(file);
被异步处理。简而言之,这意味着您的代码将继续运行(在您的情况下打印这些消息)并在数据完全加载后调用reader.onloadend
回调 - 这对您来说太晚了,因为您的消息已经打印有几种方法可以修复此代码,一种好方法是使用Promises。我个人赞成Bluebird。 使用promises,解决方案看起来像这样(伪代码):
function readFromFile(fileName) {
return new Promise(resolve, reject) {
var pathToFile = cordova.file.externalDataDirectory + fileName;
window.resolveLocalFileSystemURL(pathToFile, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (e) {
console.log("Share the results... " + JSON.parse(this.result));
resolve(JSON.parse(this.result));
};
reader.readAsText(file);
}, errorHandler.bind(null, fileName));
}, errorHandler.bind(null, fileName));
} // Return the promise
}
function some_function(callback) {
console.log("inside function1");
var promise = readFromFile(entries[i].name);
promise.then(callback); // Will be called when promise is resolved
}
some_function(console.log);
Promises允许您在概念上返回一个“契约”,即获取该值,并且一旦收到数据并且承诺得到解决,将会调用等待该值(.then
)的所有函数(您可以拒绝)一个承诺,如果它也失败了)。 (抱歉这个错误的解释,但是互联网上有很多关于它的更好的文档,我建议看看它。)
我希望它有所帮助,还有其他方法来解决这个问题,我相信,如果没有进入发电机,承诺可能是最优雅的。