我写了一些杀手Javascript。我怎样才能轻松重复使用?

时间:2015-09-09 08:41:08

标签: javascript

我一直在使用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);
};

4 个答案:

答案 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 ModulesBrowserify,这样您就可以在浏览器和NodeJS中执行exportsrequire。导出库还有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);