在发出命令之前等待Node构造函数连接到api

时间:2014-10-31 21:29:46

标签: node.js promise json-rpc

很抱歉,如果问题标题有点模棱两可,但我不完全确定如何说出来。

我正在编写一个与json-rpc api对话的NPM模块 - 这是当前的设置。

// The module
function MyModule(config) {
    // do some connection stuff here
    connected = true
}

MyModule.prototype.sendCommand = function() {
    if(connected) {
        // do command
    } else {
        // output an error
    }
}

module.exports = MyModule;

// The script interacting with the module
var MyModule = require('./MyModule');
var config = { 
    // config stuff 
};
var mod = new MyModule(config);
var mod.sendCommand;

该命令不会发送,因为此时它没有连接,我认为这是由于NodeJS的异步,非阻塞架构,我可能需要使用promises等待来自API的响应,我在哪里实现这个?我是在模块中执行此操作还是在与模块交互的脚本中执行此操作?

2 个答案:

答案 0 :(得分:1)

您需要使用回调或承诺或类似的东西来指示连接何时完成,以便您可以在通过该回调启动的更多代码中使用该连接。

虽然通常不认为在构造函数中执行异步内容是最佳做法,但可以这样做:

function MyModule(config, completionCallback) {
    // do some connection stuff here
    connected = true
    completionCallback(this);
}

var mod = new MyModule(config, function(mod) {
    // object has finished connecting
    // further code can run here that uses the connection
    mod.sendCommand(...);
});

更常见的设计模式是不将连接放在构造函数中,而是为此添加一个方法:

function MyModule(config) {
}

MyModule.prototype.connect = function(fn) {
    // code here that does the connection and calls
    // fn callback when connected
}

var mod = new MyModule(config);
mod.connect(function() {
    // object has finished connecting
    // further code can run here that uses the connection
    mod.sendCommand(...);
});

答案 1 :(得分:0)

不要使用promises,使用节点的编程模型,你不“调用函数”,但是“一旦实际可用,你就可以使用结果处理函数调用函数来处理数据”:

MyModule.prototype.sendCommand = function(handler) {
  if(connected) {
    // run stuff, obtain results, send that on:
    handler(false, result);
  } else {
    // output an error, although really we should
    // just try to connect if we're not, and say
    // there's an error only when it actually fails.
    handler(new Error("ohonoes"));
  }
}

然后将该函数称为

var MyModule = require('./MyModule');
var mod = ...
mod.sendCommand(function(err, result) {
  // we'll eventually get here, at which point:
  if (err) { return console.error(err); }
  run();
  more();
  code();
  withResult(result);
});