Подождите, пока конструктор Node подключится к API, прежде чем вводить команды

Извините, если название вопроса немного двусмысленное, но я не совсем уверен, как его сформулировать.

Я пишу модуль NPM, который общается с API json-RPC - это текущая настройка.

// 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 и что мне, возможно, нужно использовать обещания для ожидания ответа от API, где Я это реализую? Я делаю это в своем модуле или в сценарии, взаимодействующем с модулем?

2 ответа

Решение

Вам нужно будет использовать либо обратный вызов, либо обещания, либо что-то в этом роде, чтобы указать, когда соединение установлено, и вы сможете использовать это соединение в дальнейшем коде, который запускается через этот обратный вызов.

Хотя, как правило, не рекомендуется делать асинхронную работу в конструкторе, это можно сделать:

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

Не используйте обещания, используйте модель программирования узла, где вы не "вызываете функции", а "вызываете функции с помощью обработчика результатов для обработки данных, когда они действительно доступны":

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);
});
Другие вопросы по тегам