0

Im having trouble to understand the following javascript code:

/**
* Outputs the result of compiling a template.
*
* @module generator.generate
* @param  {Object}        config Configuration options
* @param  {Object|String} config.asyncapi AsyncAPI JSON or a string pointing to an AsyncAPI file.
* @param  {String}        config.target_dir Path to the directory where the files will be generated.
* @return {Promise}
*/
generator.generate = config => new Promise((resolve, reject) => {
 bundleAndApplyDefaults(config)
   .then((cfg) => {
     async function start () {
       await registerHelpers(cfg);
       await registerPartials(cfg);
       await generateDirectoryStructure(cfg);
     }

     start().then(resolve).catch(reject);
   })
   .catch(reject);
});

More specifically in which order the .then's are called and what promise they belong to. I think that the first .then gets called when the method bundleAndApplyDefaults(config) is completed. But im not sure what where the parameter cfg comes from.

Inside the function start() gets called and the second .then with the resolve of the original promise gets executed, the original promise only has .catch(reject) outside the executor and no .then for success, as far as i know.

Hereby im also not sure, why there is a .then after the start method, when theres no actual promise.

I appreciate any help.

NicO
  • 591
  • 2
  • 8
  • 21
  • "*im not sure what where the parameter cfg comes from.*" it's what the promise returned by `bundleAndApplyDefaults` will pass into the `then` when resolved. – VLAZ Jan 14 '20 at 11:04

3 Answers3

4

This is horrible code, full of the Promise constructor antipattern and mixing async/await syntax with then method calls. It should simply be

generator.generate = async (config) => {
  const cfg = await bundleAndApplyDefaults(config);
  await registerHelpers(cfg);
  await registerPartials(cfg);
  await generateDirectoryStructure(cfg);
};
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This is way better to understand, thanks! But isnt there a return statement missing, as seen in the comment `@return {Promise}`? – NicO Jan 14 '20 at 12:05
  • 1
    @NicO async functions always return a promise. Also, the original code also doesn't have an explicit return - it just returns a Promise that will not have any further values, it will just be resolved eventually. – VLAZ Jan 14 '20 at 12:12
1

This is poorly written code. This is what the author meant to write:

generator.generate = config => bundleAndApplyDefaults(config).then(async (cfg) => {
    await registerHelpers(cfg);
    await registerPartials(cfg);
    await generateDirectoryStructure(cfg);
  });

This code works exactly like your code, just without the bloat.

The wrapping new Promise() is an antipattern, and comes here with the additional cost that you have to resolve/reject it by forwarding the values from the Promise that start() returns.

im also not sure, why there is a .then after the start method, when theres no actual promise.

An async function returns a Promise.

Thomas
  • 11,958
  • 1
  • 14
  • 23
0

Because start is async, it will return an implicit promise.

The MDN reference has more information.

patrickb
  • 422
  • 2
  • 9