Typescript Singleton未定义的属性



我正在尝试创建一个具有单个amqp连接的singleton,当调用createChannel方法时,它必须从同一连接返回一个新通道:

export interface IBroker {
createChannel(): Promise<IChannel>;
}
export default class Broker implements IBroker {
private static instance: Broker;
private conn: IConnection | undefined;
private constructor(public config: IRabbitMQConfig = new RabbitMQConfig()) {}
/**
* singleton
*/
public static getInstance(): Broker {
if (!this.instance) {
this.instance = new Broker();
}
return this.instance;
}
/**
* initiates configuration on infra service
*/
async createChannel(): Promise<IChannel> {
try {
if (!this.conn) {
this.conn = await this.config.init();
await this.createExchanges();
await this.createQueues();
await this.createBinds();
logger.info('Broker started successfully');
}
if (!this.conn) {
throw new InternalError('Error starting broker. Missing connection!');
}
return await this.conn.createChannel();
} catch (err) {
logger.error('Error trying to start broker', err);
throw new InternalError('Error trying to start broker', 500);
}
}
// code...

调用config.int((返回amqp连接。

当我像下面这样测试类时,每次我调用createChannel时,它都会创建一个新的连接!

const a = Broker.getInstance();
const b = Broker.getInstance();
console.log(a === b); // return true
a.createChannel(); // create a new connection
b.createChannel(); // creates another connection

调用createChannel时,Broker类的this.con始终未定义!

我认为问题是对createChannel的两个同步调用意味着第一个调用时第二个调用还没有初始化连接,这导致创建了两个连接。

如果你想使你的CCD_;线程安全";在创建连接方面,你可以做这样的事情(未经测试(:

interface IConnection {
connect: () => void
}
const initConnection = () : Promise<IConnection> => {
return Promise.resolve({
connect: () => {}
});
};
class Broker {
private connection : IConnection | undefined;
private pendingConnection : Promise<IConnection> | undefined;
async createChannel() : Promise<IConnection> {
if (this.connection) {
return this.connection;
}
if (this.pendingConnection) {
return this.pendingConnection;
}
this.pendingConnection = initConnection();
const conn = await this.pendingConnection;
// Do other setup stuff
this.connection = conn;
this.pendingConnection = undefined;
return conn;
}
}

最新更新