如何在 Node.js 中正确构建 class

How to properly structure class in Node.js

我有一个名为 TileStreamer 的 class,我目前定义如下:

function TileStreamer {

};

这个class有常量,我定义如下:

// Tiles are 256 x 256 pixels 
TileStreamer.prototype.TILE_SIZE = 256; 

// Header size in bytes
TileStreamer.prototype.HEADER_SIZE = 28; 

// Various table entry sizes in bytes 
TileStreamer.prototype.RESOLUTION_ENTRY_SIZE = 12; 
TileStreamer.prototype.TILE_COUNT_SIZE = 4; 
TileStreamer.prototype.TILE_ENTRY_SIZE = 12; 

// Offsets within header 
TileStreamer.prototype.WIDTH_OFFSET = 3; 
TileStreamer.prototype.HEIGHT_OFFSET = 4; 
TileStreamer.prototype.NUM_TABLES_OFFSET = 7; 
TileStreamer.prototype.UNPOPULATED_OFFSET = 12092;

还有其他变数。这些变量很重要,因为 它们需要从其他 classes 访问。他们在这个 class 的方法中获取他们的值。就结构而言,这是我不确定的。我目前正在尝试的是:

TileStreamer.prototype.header; 
TileStreamer.prototype.resolutionEntry; 
TileStreamer.prototype.resolutionTable; 
TileStreamer.prototype.filepath; 
TileStreamer.prototype.s3; 
TileStreamer.prototype.level; 
TileStreamer.prototype.ncols; 
TileStreamer.prototype.nrows; 
TileStreamer.prototype.nlevels; 
TileStreamer.prototype.toffset; 
TileStreamer.prototype.tsize; 
TileStreamer.prototype.modifiedTime; 
TileStreamer.prototype.tile; 
TileStreamer.prototype.host; 
TileStreamer.prototype.bucket; 

这个class还有方法如:

TileStreamer.prototype.Init = function(filepath, index, s3config){
   var retval = false; 
   AWS.config.update({accessKeyId: s3config.access_key, secretAccessKey: s3config.secret_key});
   var blc = new BlockLibraryConfigs(); 
   var awsConfig = blc.awsConfig; 
   AWS.config.update({region: awsConfig.region}); 

   var aws = new AWS.S3(); 
   var params = {
       Bucket: s3config.bucket, 
       Key: s3config.tile_directory + filepath, 
       Range: 'bytes=0-' + (this.HEADER_SIZE - 1)
   };

    aws.getObject(params, function(err, data){
       if(err == null){
            TileStreamer.modifiedTime = data.LastModified; 
            var header = bufferpack.unpack('<7I', data.Body);
            TileStreamer.header = header; 
            TileStreamer.nlevels = header[TileStreamer.NUM_TABLES_OFFSET]; 

            if(TileStreamer.nlevels == 5){
                TileStreamer.level = 0; 
                TileStreamer.ncols = Math.ceil((header[TileStreamer.WIDTH_OFFSET] * 1.0) / TileStreamer.TILE_SIZE); 
                TileStreamer.nrows = Math.ceil((header[TileStreamer.HEIGHT_OFFSET] * 1.0) / TileStreamer.TILE_SIZE);   

            }  
       }

    });     

}; 

上面的方法应该设置一些变量的值,比如modifiedTime,这样我就可以在另一个class中访问它,比如:

TileStreamer = require('tilestreamer.js'); 
var ts = new TileStreamer();
ts.Init(parPath, index, config); 
var last_modified = ts.modifiedTime; 

只需在创建对象时将要初始化的任何 public 属性直接放入 init 函数中即可。这是一个小例子...

function TileStreamer() {
};

TileStreamer.prototype.Init = function() {
    this.modifiedTime = new Date();
}; 

var ts = new TileStreamer();
ts.Init();
console.log(ts);

jsfiddle 示例

https://jsfiddle.net/v6muohyk/

要解决您在异步函数的回调中设置对象属性时遇到的问题,只需创建一个本地可访问变量来引用您当时正在创建的对象...

TileStreamer.prototype.Init = function() {
    var thisTileStreamer = this;
    asynchFunction(function(err, data) {
        thisTileStreamer.modifiedTime = data.lastModified;
    });
};

更进一步,如果您需要在 init 函数完成后执行一些代码,那么这也需要等待异步函数完成。为此,将另一个参数传递给 init,这是一个在所有工作完成后要执行的函数...

TileStreamer.prototype.Init = function(callback) {
    var thisTileStreamer = this;
    asynchFunction(function(err, data) {
        thisTileStreamer.modifiedTime = data.lastModified;
        callback();
    });
};

var ts = new TileStreamer();
ts.Init(function() {
    // put code here that needs to be executed *after* the init function has completed
    alert(ts.modifiedTime);
});