Skip to content

Use promise-returning code without async/await

I’m trying to quickly write a simple tool in NodeJS using pdf-lib. pdf-lib appears to be designed to use promises and async/await, but I don’t want the extra code complexity of async/await for such a simple tool.

How can I use functions that return a promise without the extra bother of async/await?

Answer

Since the library primarily uses Promises, you will have to learn how to use Promises regardless, if you want to be able to use the library.

If you think async/await will be too difficult, you can construct .then chains instead. When you start with a Promise or have a Promise inside a .then, make another .then, whose callback will run when the Promise resolves. For example, this:

const pdfDoc = await PDFDocument.load(existingPdfBytes)

// Embed the Helvetica font
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)

if you want to do away with async/await, can be

// first Promise
PDFDocument.load(existingPdfBytes)
  .then((pdfDoc) => {
    // second Promise: return it so its resolve value can be used in the next `.then`
    return pdfDoc.embedFont(StandardFonts.Helvetica);
  })
  .then((helveticaFont) => {
    // helveticaFont is now available inside this `.then`
  })
  .catch(handleErrors); // don't forget this

Or you could nest the second .then inside to have access both to pdfDoc and helveticaFont at once, or use Promise.all:

PDFDocument.load(existingPdfBytes)
  .then((pdfDoc) => {
    return pdfDoc.embedFont(StandardFonts.Helvetica)
      .then((helveticaFont) => {
        // both helveticaFont and are available inside this `.then`
      });
   })
  .catch(handleErrors);

or

const pdfDoc = await 
// first Promise
PDFDocument.load(existingPdfBytes)
  .then((pdfDoc) => {
    return Promise.all([pdfDoc.embedFont(StandardFonts.Helvetica), pdfDoc]);
  })
  .then(([helveticaFont, pdfDoc]) => {
    // both helveticaFont and are available inside this `.then`
   })
  .catch(handleErrors);

But, as you can see, it gets really messy when you have lots of asynchronous requests to make. I’d highly recommend using async/await here if at all possible – it’ll make things much easier and much less complicated. On the contrary, deliberately avoiding async/await will probably make things significantly (and unnecessarily) more tedious.