Reputation: 1324
I'm trying to have a Singleton instance of a dynamically imported module in my Next.js app. However, the current implementation I have seems to initialize a new instance every time I call getInstance
.
Here's the implementation in gui.js
:
let dynamicallyImportPackage = async () => {
let GUI;
await import('three/examples/jsm/libs/dat.gui.module.js')
.then(module => {
GUI = module.GUI
})
.catch(e => console.log(e))
return GUI;
}
let GUI = (function () {
let instance;
return {
getInstance: async () => {
if (!instance) {
let GUIModule = await dynamicallyImportPackage();
instance = new GUIModule();
}
return instance;
}
};
})();
export default GUI;
and I call it in an ES6 class function using GUI.getInstance().then(g => { ... })
I would normally use React Context API or Redux for this kind of shared state but for this case, I need it to be purely in ES6 JS and not React.
Upvotes: 2
Views: 3500
Reputation: 664538
You need to cache the promise, not the instance, otherwise it will try to import the module (and instantiate another instance) again while the first is still loading and has not yet assigned the instance
variable.
async function createInstance() {
const module = await import('three/examples/jsm/libs/dat.gui.module.js')
const { GUI } = module;
return new GUI();
}
let instancePromise = null;
export default function getInstance() {
if (!instancePromise) {
instancePromise = createInstance()
// .catch(e => {
// console.log(e); return ???;
// instancePromise = null; throw e;
// });
}
return instancePromise;
}
Upvotes: 3