0

I'm using Mozilla's PDF.js module in a Promise in order to get every PDF page transformed into a JPG image. My code creates the file images with the help of the fs module, and it is used as a Promise with the promisify function on the utils module. At this point the code works perfectly, but I had place a Resolve function after, and it is not being fired, and the Promise is hanging. Where should I put the resolve?

I've tried at the end of the function, but I'm affraid that the way I'm handling the Promise is not completely executed, and I'm being stoock because the implementation of the Promise that I had to do in order to get the PDF.js module working

const CanvasFactory = require('./../../lib/canvas/canvas');
const pdfjsLib = require('./../../lib/pdf.js/node_modules/pdfjs-dist');

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

const writeFile = promisify(fs.writeFile);
const convertPDF2PNG = (pdfFilePath) => new Promise((resolve, reject) => {
  const loadingTask = pdfjsLib.getDocument(pdfFilePath);
  loadingTask.promise.then((pdf) => {
    const maxPages = pdf.numPages;
    const convertPDFPromises = [];
    for (let i = 1; i <= maxPages; i += 1) {
      const page = pdf.getPage(i);
      convertPDFPromises.push(page.then(page => {
        const viewport = page.getViewport({ scale: 1.0 });
        const canvasFactory = new CanvasFactory();
        const canvasAndContext = canvasFactory.create(viewport.width, viewport.height);
        const renderContext = {
          canvasContext: canvasAndContext.context,
          viewport,
          canvasFactory,
        };
        const renderTask = page.render(renderContext);
        renderTask.promise.then(() => {
          const image = canvasAndContext.canvas.toBuffer();
          writeFile(`temporal/output${i}.jpg`, image)
            .then(() => {
              // TODO: add query to insert images in Database
              console.log(`File ${i} added`);
            })
            .catch(writeErr => {
              console.error(writeErr)
              reject(writeErr);
            });
          })
          .catch(err => {
            console.error(err);
            reject(err);
          }); 
      }));
    }
  })
  .catch(reason => {
    console.error(reason);
    reject(reason);
  });
  resolve();
});

This is the responses I get on the console

File 2 added
File 3 added
File 1 added

I want to know why the Promise is not being resolved.

  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! To deal with the loop, use `Promise.all`. – Bergi Mar 27 '19 at 19:12
  • I agree with the above comment. Heres an example of three simultaneous promises being cast and returned in an imperative manner. `let [targetsDaily, targetsMonthly, targetsYearly] = await Promise.all([ this.downloadTargets(map.daily), this.downloadTargets(map.monthly), this.downloadTargets(map.yearly) ])` – Screll Mar 27 '19 at 19:36
  • Ok, so the anti-pattern is the for loop? not the `const convertPDF2PNG = () => new Promise((resolve, reject) => {}))` itself? –  Mar 27 '19 at 19:42

0 Answers0