Async function from callback in JavaScript

A function can return a promise or require a callback as an argument. In the former case, we can use await syntax in the function call. Wrapping function into a Promise allows using the same style in the latter case.

The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
MDN async function

The async library function might require a callback instead of returning a promise. The async/await style is still possible in this case by wrapping function call into Promise.

Let's review an example of using an SNS message validator library. The library exposes the MessageValidatorclass with the following signature.

declare class MessageValidator {
    // ...
    validate(hash: string | object, cb: (err: Error | null, message?: object) => void): void;
}

We plan to invoke the validate method using await syntax instead of nested callback functions. Code speaks for itself.

const validator = new MessageValidator()

const err = await new Promise((resolve) => validator.validate(req.body, resolve))

if (err !== null) {
  next(new InvalidSnsError());
}
next();

In our example, we do not need the second callback argument and ignore it. However, we can have in case we need it.

const { err, message } = await new Promise(
  (resolve) => validator.validate(req.body, (err, message) => resolve({err, message})));