模块返回异步初始化对象

时间:2016-12-29 17:07:32

标签: javascript node.js asynchronous initialization return-value

我遇到了这个让我疯狂的“设计”问题。

我的目标是拥有一个解耦的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-是否有任何奇特的解决方案允许第三方代码执行简单的“发布(交换,通道,消息)”,确保已建立连接?

我觉得能够和JS一起工作,但有时候你只需要做一件事就知道你可以这样做,但这让我头疼。

真的非常感谢,我希望能够理解这个问题:)

1 个答案:

答案 0 :(得分: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));
  }
};