我一直在使用Chromes filestorage API。我已经构建了一些函数,它们一起自动下载一个json对象并将其存储为字符串。如果最后一次服务器请求是在24小时内完成的。我自动使用该文件的最新版本。我使用它来管理我进行统计分析的巨大数据转储。
整个系统只有一个需要暴露的功能。这是getData
。
目前所有这些功能都是全局变量。我应该如何有条不紊地把它包含在内。
//This file will cache serverdata every day.
var onInitFs,
errorHandler,
fileSystemInit,
saveFile,
readFile,
fileSystem,
getData;
//request rights to save files to system.
fileSystemInit = function(){
//Browser specific
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
navigator.webkitPersistentStorage.requestQuota(1048*1048*256, function(grantedBytes) {
//once approved (or if previously approved):
window.requestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler);
}, function(e) {
console.log('Error', e);
});
};
//make filesystem global.
onInitFs = function(fs) {
fileSystem = fs;
};
fileSystemInit();
saveFile = function(url, content, callback){
var filename = makeFilename(url)
if(!fileSystem){
console.log('no filesystem registered')
return;
}
fileSystem.root.getFile(filename, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([JSON.stringify(content)], {type: 'application/json'});
fileWriter.write(blob);
fileWriter.onwriteend = function(e) {
console.debug('Write completed.', e);
if(callback){
callback();
}
};
fileWriter.onerror = function(e) {
console.log('Write failed: ', e);
};
}, errorHandler);
}, errorHandler);
};
readFile = function(url, callback){
var filename = makeFilename(url)
if(!fileSystem){
console.log('no filesystem registered');
return;
}
fileSystem.root.getFile(filename, {}, function(fileEntry){
//this object reads files.
var reader = new FileReader();
//register callback for read files
reader.onloadend = function(e){
var callbackValue = JSON.parse(this.result)
callback(callbackValue);
};
//read file-function
fileEntry.file(function(file){
reader.readAsText(file);
},errorHandler);
},errorHandler);
};
makeFilename = function(url){
return url.replace(/\W/g, '') +'.json'
}
errorHandler = function(e) {
console.log('Error: ', e);
};
getData = function(url, callbackNewData, callbackOldData){
var lastDownloaded = localStorage.getItem(url+'lastDownloaded'),
oneDay = 1000*60*60*24;
//update data if the data is old.
window.setTimeout(function(){
if(!lastDownloaded || new Date()-new Date(lastDownloaded) > oneDay ){
console.debug('downloading '+url);
d3.json(url, function(data){
localStorage.setItem(url+'lastDownloaded',new Date());
console.debug('saving '+url);
saveFile(url, data, function(){
callbackNewData(url);
});
});
}else{
callbackOldData(url);
}
}, 200);
};
答案 0 :(得分:2)
您可以将整个事物包装在匿名函数中并仅公开getData。这是最简单的方法。
var getDataFromUrl = function () {
//This file will cache serverdata every day.
var onInitFs,
errorHandler,
fileSystemInit,
saveFile,
readFile,
fileSystem,
getData;
// Your original code here ...
return getData; // This exposes the getData function.
})();
通过这种方式,您只会公开一个全局函数getDataFromUrl
,它正是公共API。
对于更现代的用法,您可能需要查看Common JS Modules和Browserify,这样您就可以在浏览器和NodeJS中执行exports
和require
。导出库还有UMD Pattern。
答案 1 :(得分:0)
(function(window){
'use strict'
var onInitFs,errorHandler,fileSystemInit,saveFile,readFile,fileSystem,getData;
fileSystemInit = function(){
// your code
};
//make filesystem global.
onInitFs = function(fs) {
//your code
};
fileSystemInit();
saveFile = function(url, content, callback){
//your code
};
readFile = function(url, callback){
//your code
};
makeFilename = function(url){
//your code
}
errorHandler = function(e) {
//your code
};
getData = function(url, callbackNewData, callbackOldData){
//your code
};
window.HimmatorsFileStorageAPI = getData; // you can change the name here
})(window);
您可以通过在页面中包含此脚本然后调用
来使用它 HimmatorsFileStorageAPI(url, callbackNewData, callbackOldData);
答案 2 :(得分:0)
Module
模式将是一个良好的开端:http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
伪类也很棒:
var StorageInterface = function(arg1, arg2){
this.arg1 = arg1;
this.arg2 = arg2;
}
StorageInterface.prototype.method = function(arg3, arg4){
return arg3 + arg4 + this.arg1 + this.arg2;
}
var si = new StorageInterface(100, 500);
si.method(3, 4);
答案 3 :(得分:0)
只需将其打造成原型:-)并使用一些范围实例(使用var that = this
)将元素传递回来自不同范围的父对象。
现在你可以开始new FileSystemInstance()
来发挥你的魔力。
如果您希望将更多“神秘”方法设为私有,您可以考虑将它们移动到对象内的对象等,但最终任何具有真正毅力的人都能够访问它们。因此,我建议采用公共方式,并命名私有方法_fileSystemInit
,因此阅读代码的人都知道它是一种内化方法。
//This file will cache serverdata every day.
function FileSystemInstance() {
this.fileSystem = null;
this.requestFileSystem = null;
this.fileSystemInit();
}
//request rights to save files to system.
FileSystemInstance.prototype.fileSystemInit = function(){
//Browser specific
this.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
this.requestFileSystem = this.requestFileSystem.bind(window);
console.log(this.requestFileSystem);
var that = this;
console.log(that.requestFileSystem);
navigator.webkitPersistentStorage.requestQuota(1048*1048*256, function(grantedBytes) {
//once approved (or if previously approved):
console.log(that.requestFileSystem);
that.requestFileSystem(PERSISTENT, grantedBytes, function(fs){that.onInitFs(fs)}, function(e){that.errorHandler(e)});
}, function(e) {
console.log('Error', e);
});
};
//make filesystem global.
FileSystemInstance.prototype.onInitFs = function(fs) {
this.fileSystem = fs;
};
FileSystemInstance.prototype.saveFile = function(url, content, callback){
var filename = this.makeFilename(url)
if(!fileSystem){
console.log('no filesystem registered')
return;
}
this.fileSystem.root.getFile(filename, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([JSON.stringify(content)], {type: 'application/json'});
fileWriter.write(blob);
fileWriter.onwriteend = function(e) {
console.debug('Write completed.', e);
if(callback){
callback();
}
};
fileWriter.onerror = function(e) {
console.log('Write failed: ', e);
};
}, errorHandler);
}, errorHandler);
};
FileSystemInstance.prototype.readFile = function(url, callback){
var filename = this.makeFilename(url)
if(!this.fileSystem){
throw new Error('no filesystem registered');
}
this.fileSystem.root.getFile(filename, {}, function(fileEntry){
//this object reads files.
var reader = new FileReader();
//register callback for read files
reader.onloadend = function(e){
var callbackValue = JSON.parse(this.result)
callback(callbackValue);
};
//read file-function
fileEntry.file(function(file){
reader.readAsText(file);
},errorHandler);
},errorHandler);
};
FileSystemInstance.prototype.makeFilename = function(url){
return url.replace(/\W/g, '') +'.json'
}
FileSystemInstance.prototype.errorHandler = function(e) {
console.error('Error: ', e);
};
FileSystemInstance.prototype.getData = function(url, callbackNewData, callbackOldData){
var that = this;
var lastDownloaded = localStorage.getItem(url+'lastDownloaded'),
oneDay = 1000*60*60*24;
//update data if the data is old.
window.setTimeout(function(){
if(!lastDownloaded || new Date()-new Date(lastDownloaded) > oneDay ){
console.debug('downloading '+url);
d3.json(url, function(data){
localStorage.setItem(url+'lastDownloaded',new Date());
console.debug('saving '+url);
that.saveFile(url, data, function(){
callbackNewData(url);
});
});
}else{
callbackOldData(url);
}
}, 200);
};
FileSystem = new FileSystemInstance();
var data = FileSystem.getData();
console.log("Data is: ",data);