Node.js中面向对象的设计

时间:2013-01-16 10:02:30

标签: javascript performance oop node.js modularity

我正在努力使用 Node.js async 流程。假设您有以下课程:

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和Node结构,我当然认为我的设计存在一些重大问题,但由于必须调用connect 以便任何操作都能正常工作,我无法找到解决方法正常。但是当我在操作后进行一些记录时:

brandNewObject = myClass();
brandNewObject.connect();
brandNewObject.get();

我观察到在获取全局isConnected变量之前调用了get函数。如果不实际违反Node的异步结构,我该怎么做呢?

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

3 个答案:

答案 0 :(得分:1)

你必须使用回调。

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();
});

答案 1 :(得分:1)

为您的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();
});

答案 2 :(得分:1)

对此有不同的解决方法。

一种简单的方法类似于你正在做的事情

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
    }
  }
})
};

HTH