2

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.

1 Answer 1

3

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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.