vyancharuk/nodejs-todo-api-boilerplate

Anonymous async function needed in app.ts?

Closed this issue · 4 comments

Hey @vyancharuk, thanks for publishing this project! I was just going through the files and wondered why you would use the anonymous async function to call initLoaders():

(async () => {
await initLoaders();
})();

I removed the async in line 7 and the anonymous function in lines 12-14 and the app worked just the same.

Is there a reason for this setup I am overseeing right now?

I also added a timeout in loaders/index.ts and recognized that the initLoaders() function in app.ts is not waiting on initDI(), expressLoader(...) and checkEnvs() (which I would expect in this place). So currently there is no reason to use async/await in this context, right?

Hi @bene-we, thank you for paying attention to boilerplate.

The short answer on your question, yes, async function needed in app.ts to keep it possible to have async loaders

More detailed answer:

I removed the async in line 7 and the anonymous function in lines 12-14 and the app worked just the same.

Yep, currently, all loaders are synchronous, so it is possible to remove async/await for initLoaders in app.ts and async for init in loaders/index.ts and everything will work

I also added a timeout in loaders/index.ts and recognized that the initLoaders() function in app.ts is not waiting on initDI(), expressLoader(...) and checkEnvs() (which I would expect in this place)

I've just added await statement for each loader call so that it will wait for all async initialization

I plan to update it soon with some other improvements.
I hope it works for you, thanks!

Thanks for your reply!

Okay I see why I can remove the code, but I added a setTimeout in loaders.init(...) and would expect the log After loaders initialized at the end.

I used the following code:

app.ts

async function initLoaders() {
  await loaders.init({ expressApp: app });

  logger.info('After loaders initialized');
}

(async () => {
  await initLoaders();
})();

loaders/index.ts

const init = async ({ expressApp }: { expressApp: Application }) => {
  await setTimeout(() => {
    initDI();
    expressLoader({ app: expressApp });
    checkEnvs();
  }, 3000);
};

In this case the logs from initDI() and expressLoader(...) are written to the console 3 seconds after After loaders initialized:
image

I would expect it to wait on the loaders, but I probably get something wrong with async/await. Though it works if I return a promise from loaders.init():

const init = async ({ expressApp }: { expressApp: Application }) => {
  return new Promise((resolve) => {
    setTimeout(async () => {
      await initDI();
      await expressLoader({ app: expressApp });
      await checkEnvs();
      resolve();
    }, 3000);
  });
};

Console output:
image

Nevertheless I will check out your improvements later on, thanks again! Issue can be closed.

Okay I think I got it: if the loader functions would be async (therefore returning promises) it would work as I outlined, just tested it with export default async ({ app }: { app: Application }) ... and a setTimeout within. So it is all just prepared to load everything asychronously.

Thanks for your help!

So it is all just prepared to load everything asychronously.

Correct.
You are welcome!