1

The old wait for data to be loaded thing.

I have a module that uses asynch request to load data from local storage.

The scripts that uses this module have to wait for it to load the data before initializing.

I can use something like this (Here a dummy function that "sleeps" for 1 second), two files in one sample:

// data.js: The wait for it module
const load_things = new Promise(resolve => {
    setTimeout(()=> resolve(), 1000);
});
const load = async () => {
    await load_things;
    return true;
};
const data = {
    load: load(),
    foo: () => { /* something else from this module */ }
};
// export {data};

// ====================================================

// user.js: The script using the module
// import {data} from 'data.js';

const init = async () => {
    const ready = await data.load;
    console.log('Proceed:', ready);
    // use the data module
};

init();

It feels a bit wonky and one are left with a Promise instead of a simple boolean on the data object.

My question is if this way of doing it is way off or something else?

I pondered about using Event and fire that from the data.js module, but issue with that is if the Event is fired before any user script has added a listener. One could of course add a property like loaded: true|false to the exported object and do something like:

if (data.loaded === false)
    foo.addEventListener('dataLoaded', init)
else
    init()

But not sure if that is a better approach. It leaves more to the user script. A simple await or .then() is a bit cleaner, or? Not sure.

3
  • The standard answer is to not initiate anything in data.js. Let the module that imports it (synchronously) initiate the load
    – danh
    Commented Jul 5, 2022 at 17:35
  • @danh But isn't it better to do the load() call as early as possible if it is a required loaded state? I add the data script before any other to let the load state begin / the asynch calls to be made.
    – Smorfph
    Commented Jul 5, 2022 at 17:38
  • The earliest possible is after the import. It's really just as early as before the import.
    – danh
    Commented Jul 5, 2022 at 17:43

1 Answer 1

2

Export a loader (the thing that loads, not the loaded thing). Use it right after import.

// data.js: The "you can't wait for it" module
const load_things = new Promise(resolve => {
    setTimeout(()=> resolve(), 1000);
});
const loader = async () => {
    await load_things;
    return true;
};
export default {
    loader: loader,  // mention it, don't invoke it
    foo: () => { /* something else from this module */ }
};

The importer says:

import object from 'data.js'

object.loader().then(data => {
  // use data and object
})
1
  • My thought behind asking was more in line with the comment under question (I.e. start load as soon as possible). But if it does not matter much then it's a waste of time to work on :P
    – Smorfph
    Commented Jul 5, 2022 at 17:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.