How to await in a chain?

This is a Azure Function httpTrigger in node.js. How to wait for f1() finishes then calls f2()?

model.exports = main(param)  // async main plus await f1(param) don't wait either.
{
  f1(param)
  .then(
    good => f2(good, callback),  // execution jumps into f2 without waiting for f1 finishes
    bad => {...}
  );
}

async function f1(param)
{
  try
  {
    // await NOT wait here, 
    // but waits in Express
    await googlelib.verifyIdToken(something, (err, ok) =>
    {
      if (err) { return Promise.reject("Invalid"); }
      else     { return Promise.resolve("OK"); }
    });
  }
  catch (e) { return Promise.reject("catch"); }
}
      

Solution 1:

If googlelib.verifyIdToken() supports promises as a built-in part of its interface (as long as you do not pass it a callback), then you can change your code to this:

function f1(param) {
    return googlelib.verifyIdToken(something);
}

And, you will just directly return the promise that googlelib.verifyIdToken() provides, allowing the caller to use either await or .then() on the result that f1(...) returns.


If googlelib.verifyIdToken() does not support promises as a built-in part of its interface (when you do not pass it a callback), then you can "promisify" it yourself:

const {promisify} = require('util');

// create promisified interface .verifyIdTokenP
googlelib.verifyIdTokenP = promisify(googlelib.verifyIdToken);

// use that promisified interface
function f1(param) {
    return googlelib.verifyIdTokenP(something);
}

This process of manually promisifying a function works for any asynchronous API that supports the "nodejs asynchronous calling convention" where the function accepts a callback as the last argument and that callback will be called with two arguments as callback(err, value). If the asynchronous API works differently than this, then you can't use the util.promisify() function for it and would have to manually wrap it in your own promise.