1

У меня проблема с «дизайном», которая сводит меня с ума.Модуль, возвращающий асинхронно инициализированный объект

Моей целью является развязанный клиент RabbitMQ. Он должен иметь возможность инициировать его соединение и «возвращать» созданный канал, чтобы мой издательский модуль мог его использовать.

Код выглядит следующим образом (я знаю, что это не лучший код, но я ожидаю, что он послужит для этого объяснения).

var createConnection = (function() { 

var channel; 
var connect = function(){ 
     // amqp connect 
     // error handling 
     createChannel(); 
    }); 
} 

var createChannel = function(){ 
    //amqpConn.createConfirmChannel... 
} 

//pseudo 
return{ 
    getChannel : function(){ 
     if(!initiated) 
      connect(); 
     return channel; 
    } 
} 
})(); 

module.exports = createConnection; 

Теперь важные вещи:

1- Я знаю, что это не сработает, и я знаю, почему, его упрощение.
2- Я знаю, что могу выполнить свои цели, используя асинхронные или обещания.
3- Может не имеет смысла развязывающего клиент кролика, но для понимания целей

Тем не менее, мои вопросы:

1- Есть ли способ, я могу сделать это без использования других модулей?
2- если это так, может быть выполнено необычным и стильным способом?
3- Есть ли какое-нибудь причудливое решение, позволяющее стороннему коду выполнять простой «publish (exchange, channel, msg)», было ли установлено, что соединение установлено?

Я чувствую себя способным работать с JS, но иногда вам просто нужно что-то делать, только чтобы знать, что вы можете, но это дает мне головную боль.

Действительно спасибо и я надеюсь, что этот вопрос был понят :)

+1

Может быть, используя обещание? – epascarello

+0

Привет и спасибо за ваш ответ :) Как я заявил: 2- Я знаю, что могу выполнить свои цели, используя асинхронные или обещания. Итак, если это невозможно сделать без обещаний, все в порядке. Мне нужно знать, есть ли хороший способ сделать это без использования других модулей. С уважением. – Damont

+0

Не отвечает на ваш вопрос напрямую, но вместо того, чтобы экспортировать что-то асинхронное, я обнаружил, что проще экспортировать функцию, которая будет создавать соединение для вас после его вызова, но явно, а не лениво. Затем вы можете настроить раздел начальной загрузки вашего приложения, который будет создавать экземпляр соединения и предоставлять его другим модулям, когда он будет готов.Способ, которым вы его настроили, если два модуля называют 'getChannel' одновременно, они, вероятно, оба будут называть' connect' (в зависимости от того, где вы положили этот переключатель 'Init = true'). – dvlsg

ответ

0

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

Например, вы можете обернуть объект channel в другой объект, который представляет те же методы, но внутренне проверяет, инициализирован ли фактический объект channel. Если это так, используйте его как обычно. Если это не так, дождитесь его инициализации и использования в обычном режиме. Пользователю объекта-обертки не нужно знать, действительно ли канал инициализирован. Основным недостатком этого является каждый метод обертки, который должен иметь доступ к channel, должен быть асинхронным, даже если метод, к которому он обращается по адресу channel, является синхронным.

Пример:

function initializeChannel() { 
    return new Promise((resolve, reject) => { 
    // create, initialize, and resolve channel 
    }); 
} 

module.exports = { // wrapper 
    channelPromise: initializeChannel(), 
    foo(a) { 
    return this.channelPromise.then((channel) => channel.foo(a)); 
    } 
}; 
Смежные вопросы