Estoy tratando de sincronizar un singleton. Tendría que hacer este método como el equivalente de sincronizado en Java. Lo que me sucede es que debido a que el socket tarda un tiempo, si las dos primeras solicitudes están muy juntas, se crean dos websockets. (Luego del tercero en adelante toma la instancia correctamente).
import io from 'socket.io-client'; export default class SocketIo { static socket = null; static instance = null; async initialize() { this.socket = await io(`http://${ip}:10300/`, { transports: ['websocket'], }); } static async getInstance() { logger.info('socketIo.api.getInstance: BEGIN'); if (!this.instance) { logger.info('socketIo.api.getInstance: creating new socket instance...'); try { const o = new SocketIo(); await o.initialize(); this.instance = o; logger.info('socketIo.api.getInstance: socket instance created SUCCESSFULLY'); } catch (e) { moaLog('socketIo.api.getInstance: ERROR: ', e); throw e; } } else { logger.info('socketIo.api.getInstance: a socket instance already exists, reusing that one'); } logger.info('socketIo.api.getInstance: END'); return this.instance; } }en main.js
var socket1 = SocketIo.getInstance(); var socket2 = SocketIo.getInstance(); // ... after a while var socket3 = SocketIo.getInstance(); 2022-06-16T17:53:40.658Z: socketIo.api.getInstance: BEGIN 2022-06-16T17:53:40.660Z: socketIo.api.getInstance: creating new socket instance... 2022-06-16T17:53:41.140Z: socketIo.api.getInstance: BEGIN 2022-06-16T17:53:41.141Z: socketIo.api.getInstance: creating new socket instance... 2022-06-16T17:53:41.379Z: socketIo.api.getInstance: socket instance created SUCCESSFULLY 2022-06-16T17:53:41.382Z: socketIo.api.getInstance: END 2022-06-16T17:53:41.411Z: socketIo.api.getInstance: socket instance created SUCCESSFULLY 2022-06-16T17:53:41.415Z: socketIo.api.getInstance: END ... 2022-06-16T17:56:13.076Z: socketIo.api.getInstance: BEGIN 2022-06-16T17:56:13.078Z: socketIo.api.getInstance: a socket instance already exists, reusing that one 2022-06-16T17:56:13.079Z: socketIo.api.getInstance: ENDY desde la vista del servidor veo dos conexiones websocket.
¿Algunas ideas?
A continuación se muestra un intento de sincronizar su singleton. La idea es almacenar la promesa o.intitialize y comprobar si ya se ha adquirido antes.
Agregué un uid , un valor aleatorio establecido en initialize para mostrar que solo se crea una instancia.
class SocketIo { static instance = null; static _lock = null; async initialize() { this.uid = Math.random(); } static async getInstance() { console.log('socketIo.api.getInstance: BEGIN'); if (!this.instance) { console.log('socketIo.api.getInstance: creating new socket instance...'); const o = new SocketIo(); if (!this._lock) { this._lock = o.initialize(); await this._lock; this.instance = o; console.log('socketIo.api.getInstance: socket instance created SUCCESSFULLY'); this._lock = null; } else { await this._lock; } } console.log('socketIo.api.getInstance: END'); return this.instance; } } async function Main() { var socket1 = SocketIo.getInstance(); var socket2 = SocketIo.getInstance(); console.log((await socket1).uid); console.log((await socket2).uid); } Main()Compáralo con tu versión:
class SocketIo { static instance = null; async initialize() { this.uid = Math.random(); } static async getInstance() { console.log('socketIo.api.getInstance: BEGIN'); if (!this.instance) { console.log('socketIo.api.getInstance: creating new socket instance...'); const o = new SocketIo(); await o.initialize(); this.instance = o; console.log('socketIo.api.getInstance: socket instance created SUCCESSFULLY'); } console.log('socketIo.api.getInstance: END'); return this.instance; } } async function Main() { var socket1 = SocketIo.getInstance(); var socket2 = SocketIo.getInstance(); console.log((await socket1).uid); console.log((await socket2).uid); } Main()Espero que esto sea lo que te conviene.