0

I have this cloud function:

const initCompress = async () => {
  try {
    logger.log('This shows before the function terminated');
    await mkdirp('../../../xxxxx'); <<<< WHY IS IT NOT WAITING FOR THIS TO COMPLETE?
    logger.log('This shows after the function terminated');
    return { success: true };
  } catch (err) {
    ...
  } finally {
    ...
  }
};
export default initCompress;

It is executed via:

const main = async () => {
  exports.compressImage = functions.https.onCall((data, context) => {
    initCompress(data, context);
  });
}

The console log shows:

functions: Beginning execution of "compressImage"
>  {"severity":"INFO","message":"This shows before the function terminated"}
functions: Finished "compressImage" in ~1s
>  {"severity":"INFO","message":"This shows after the function terminated"}

I'm probably doing something silly, but what? Do I need to await something somewhere?

Ben
  • 2,957
  • 2
  • 27
  • 55
  • Show us the logger, because if the logger, internally, uses promises (to prevent slowing down the main thread), it would actually show after the main promise would finish. – Akxe May 11 '21 at 18:51
  • 1
    What exactly is unexpected/wrong with your console output? And what is `compressImage` - you haven't shown that code? What is logging these lines that begin with `functions: …`? – Bergi May 11 '21 at 18:52
  • @Bergi `compressImage` is a cloud function. I expected the logs to show before the function terminated. – Ben May 11 '21 at 18:54
  • @Akxe good point, I'll check the logger. – Ben May 11 '21 at 18:54
  • @Ben And what does `compressImage` have to do with `modifyImage`? – Bergi May 11 '21 at 19:00
  • @Bergi `compressImage` executes `modifyImage`. I'll update my question to clarify. – Ben May 11 '21 at 19:02
  • @Ben Neither `initCompress` nor the `onCall` callback do `return` the promise, so `compressImage` won't know what to wait for. I would recommend to avoid mixing `.then()` syntax with `async`/`await`. [Drop the pointless `.then((response) => { return response; })`](https://stackoverflow.com/q/41089122/1048572). – Bergi May 11 '21 at 19:16
  • @Bergi please have a look at the updated question. I simplified the code. Dropped the then catch. Still not able to get `initCompress` to wait for `mkdirp` – Ben May 11 '21 at 20:30
  • @Ben The function passed to `functions.https.onCall` still doesn't return anything to wait for. – Bergi May 11 '21 at 22:43

1 Answers1

1

What you observe is totally normal. By declaring a function as async, your make it return a Promise. That Promise is being returned immediately (it just doesn't resolve immediately). Your code is equivalent of this:

const mkdirp = () => Promise.resolve();
const logger = console;

const modifyImage = () => {
  logger.log('This shows before the function terminated');
  return mkdirp('../../../xxxxx')
    .then(() => logger.log('This shows after the function terminated'))
    .then(() => ({ success: true }))
    .catch(logger.error);
};

modifyImage().then(logger.log);
logger.log('Function finished');

As a conclusion, never forget that async/await is just syntaxic sugar over Promises

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • I understand that mkdirp is an async function, so I guess my question is how to contain async functions inside a main function that only terminates once all async functions in it completed. I need to let the client know when it all finished, or when something failed. For now, I can only inform the function fired. – Ben May 11 '21 at 19:56
  • As you are using an asynchronous function, your "client" has to handle asynchronism either with a callback or with a promise. What is it exactly? – Guerric P May 11 '21 at 20:06
  • I simplified my async function even more. Please have a look at my question I tried everything - try catch, only then and catch. I am unable to execute initCompress and wait for the final response. – Ben May 11 '21 at 20:29
  • 2
    Have you tried to simply `return initCompress(data, context);`? Firebase's `functions.https.onCall` accepts `Promise` as return value – Guerric P May 11 '21 at 20:40
  • 1
    Yes. That's was it. I knew it was something silly that I did. Thank you! – Ben May 11 '21 at 20:43