Javascript Node.js中的面向对象设计

Javascript Node.js中的面向对象设计,javascript,performance,oop,node.js,modularity,Javascript,Performance,Oop,Node.js,Modularity,我正在努力处理Node.js的异步流。假设您有以下类别: function myClass() { var property = 'something'; var hasConnected = false; this.connect = function(params) { //Some logic that connects to db and in callback returns if the connection is successful connectT

我正在努力处理Node.js的异步流。假设您有以下类别:

function myClass() {
  var property = 'something';
  var hasConnected = false;

  this.connect = function(params) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult
    })
  };

  this.get = function(params) {
    if(hasConnected) {
      DoGetOperation() //
    }
    else {
      //Another question. What should be done here. Call the connect again?
    }
  }
}
考虑到Javascript和节点结构,我当然认为我的设计存在一些主要问题,但我无法找到解决方法,因为必须调用
connect
,才能使任何操作正常工作。但当我在操作后进行一些日志记录时:

brandNewObject = myClass();
brandNewObject.connect();
brandNewObject.get();
我注意到在获取全局
isConnected
变量之前调用了get函数。在不违背节点的异步结构的情况下,我可以做些什么来实现这一点


理想情况下,我正在寻找的解决方案实际上是在内部处理“连接”,而不是定义回调“外部类”

您必须使用回调

function myClass() {
  var property = 'something';
  var hasConnected = false;

  // added second parameter
  this.connect = function(params, callback) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult;
      // Now call the callback!
      callback();
    })
  };

  this.get = function(params) {
    if(hasConnected) {
      DoGetOperation() //
    }
    else {
      //Another question. What should be done here. Call the connect again?
    }
  }
}
brandNewObject = myClass();
brandNewObject.connect({}, function () {
  // this function gets called after a connection is established
  brandNewObject.get();
});

将回调参数添加到
connect
方法中

  this.connect = function(params, callback) {
    //Some logic that connects to db and in callback returns if the connection is successful
    connectToSomeDB('ConnectionString', function(connectionResult) {
      hasConnected = connectionResult;

      // Call the callback provided
      callback(params);
    })
  };
你可以这样称呼它:

brandNewObject = myClass();
brandNewObject.connect({}, function(/* optionally, "params" */) {
    brandNewObject.get();
});

这方面有不同的解决办法

一个简单的方法与您正在做的类似

this.get = function(params) {
    if (hasConnected) {
        DoGetOperation(params);
    } else {
        //here you can check the status of the connect. if it is still in 
        //progress do nothing. if the connection has failed for some reason
        //you can retry it. Otherwise send a response back indicating that the
        //operation is in progress.
    }
}
另一种方法可能是对get函数使用相同的异步回调机制,这会将方法签名更改为如下内容

this.deferredOperations = new Array();

this.get = function(params, callback) {
    if (hasConnected) {
       //using a callback as an optional parameter makes the least 
       //impact on your current function signature. 
       //If a callback is present send the data back through it, 
       //otherwise this function simply returns the value (acts synchronously).
       if (callback !== null) {
         callback(DoGetOperation(params));
       } else {
         return DoGetOperation(params);
       }
    } else {
       this.deferredOperations.push([params,callback]);
    }
}

//connect changes now
this.connect = function(params) {
//Some logic that connects to db and in callback returns if the connection is successful
connectToSomeDB('ConnectionString', function(connectionResult) {
  hasConnected = connectionResult;
  if (hasConnected && this.deferredOperations.length > 0) {
    for (var i=0; i < this.deferredOperations.length; i++) {
      var paramFunction = this.deferredOperations.pop();
      var params = paramFunction[0];
      var func = paramFunction[1];
      DoAsyncGetOperation(params, func); //Need to write a new function that accepts a callback
    }
  }
})
};
this.deferredOperations=new Array();
this.get=函数(参数,回调){
如果(已连接){
//使用回调作为可选参数使
//对当前函数签名的影响。
//如果存在回调,则通过回调发回数据,
//否则,此函数只返回值(同步操作)。
如果(回调!==null){
回调(DoGetOperation(params));
}否则{
返回DOGETOoperation(参数);
}
}否则{
this.deferredOperations.push([params,callback]);
}
}
//立即连接更改
this.connect=函数(参数){
//如果连接成功,连接到db和回调中的某些逻辑将返回
connectToSomeDB('ConnectionString',函数(connectionResult){
hasConnect=连接结果;
if(hasconned&&this.deferredOperations.length>0){
for(var i=0;i

HTH

非常感谢您的回答。但这有点违背了我所追求的模块化。原因是brandNewObject将在整个项目中使用。因此,将有多个“get”和“set”。因此,如果我想执行一个操作,我必须为每个函数建立一个连接,而不是进行一个连接,然后全局使用它。另外,myClass的目标是成为一个redisClient,因此我无法连接每个函数,因为它会显著增加客户端的数量。我知道有两种方法可以处理node.js的异步流。第一个是使用回调,正如我所建议的,第二个是使用承诺。两者都不同于“函数返回值,然后我可以使用”——您可能习惯的流(您不应该希望在node.js应用程序中有这种流)。要了解更多关于承诺的信息,我建议使用Q()