【问题标题】:How to properly structure class in Node.js如何在 Node.js 中正确构造类
【发布时间】:2016-08-29 21:53:15
【问题描述】:

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

function TileStreamer {

};

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

// 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;

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

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; 

这个类也有方法如:

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,这样我就可以在另一个类中访问它例如:

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

【问题讨论】:

  • 最简单的方法是在init函数中声明属性,加上this前缀...jsfiddle.net/v6muohyk
  • 只是想说同样的话。使用 'this' 或 TileStreamer.prototype.modifiedTime = ...;
  • @jjhavokk 因此,当我需要在异步函数中设置变量时,就像我在代码中所做的那样,是否会为同一个实例使用TileStreamer.prototype.modifiedTime = data.LastModified set modifiedTime
  • @tibsar 适用于所有实例。如果您要管理多个 TileStreamer 实例,请使用 'this'

标签: javascript node.js oop architecture


【解决方案1】:

只需在创建对象时将要初始化的任何公共属性直接放在 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);
});

【讨论】:

  • 在我的代码中,modifiedTime 之类的东西是在异步函数中设置的,那么我该如何设置呢?
  • 我已经添加了一个额外的内容来涵盖这一点。您面临的问题是您创建了一个对象,然后尝试为该类的属性设置值。所以它不是对正在创建的对象的引用。
  • 好的,试试看。所以我应该可以访问异步函数中的thisTileStreamer 变量而不将其作为参数传递?
  • 是的,它在匿名函数的范围内。除了让它发挥作用,它也让眼睛更容易:)
  • 看起来一切都在 TileStreamer 类中工作,但我在从另一个类中访问变量时遇到问题。我试过var TileStreamer = require('tilestreamer.js'); var ts = new TileStreamer(); ts.Init(parPath, index, config); var date = ts.modifiedTime;,但日期未定义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
  • 2017-06-10
  • 2020-01-09
  • 1970-01-01
相关资源
最近更新 更多