1

I have tried many variations of getting my function to return a param so that I can run my functions only when one step is complete but looking for the best way that would not get me into call back hell.

I have the following function

function convertPdfToImage(fileName) {

  return new Promise((resolve, reject) => {
    var pdfImage = new PDFImage(fileName+".pdf");

    pdfImage.convertFile().then(function (imagePaths) {
      var file = fs.createWriteStream(imagePaths);
      file.end();
      file.on("finish", () => { resolve(true); });
      file.on("error", reject);
      return resolve(true)
    });
  });
}

Which I am calling here like this:

Promise.all([convertPdfToImage('test2'), convertPdfToImage('test1')])})
    .then(function () {
      compareItems(codeId);
    });

This is the method called in the PromiseAll

function convertPdfToImage(env: string, shareClassId: string[]) {

  return new Promise((resolve, reject) => {
    var pdfImage = new PDFImage("output/" + shareClassId + env + ".pdf");

    pdfImage.convertFile().then(function (imagePaths) {
      var file = fs.createWriteStream(imagePaths);
      file.end();
      file.on("finish", () => { resolve(true); });
      file.on("error", reject);
      return resolve(true)
    });
  });
}

The problem no matter what I try, I cannot guarantee that compareItems runs after convertPdfToImage (PromiseAll has resolved)

Afshin Ghazi
  • 2,784
  • 4
  • 23
  • 37
  • Remove the `return resolve(true)`. Otherwise you resolve twice. – Jonas Wilms Feb 27 '20 at 06:58
  • Thanks. Had tried that but still nothing. I only put that to make sure it resolves. In fact without the second resolve it doesn't resolve at all – Afshin Ghazi Feb 27 '20 at 06:59
  • have you tried tocatch and log possible errors? – Jonas Wilms Feb 27 '20 at 07:07
  • Why are you calling `file.end()` BEFORE you write anything to the stream and before you install any event handlers on the stream. Those both seem wrong. Certainly your event handlers should be installed before you start writing to the stream and before you call `file.end()`. And, you do have to remove the `return resolve(true)` as that will just execute every time before any of your event handlers can ever run - rendering them useless. – jfriend00 Feb 27 '20 at 07:20

2 Answers2

1

You probably haven't implemented promises correctly,

function convertPdfToImage(fileName) {
  let pdfImage = new PDFImage(fileName+".pdf");
  return pdfImage.convertFile().then(function (imagePaths) {
    let file = fs.createWriteStream(imagePaths);
      file.end();
      file.on("finish", () => { resolve(true); });
      file.on("error", reject);
      return true 
  }).catch(err){
    console.log(err);
  }
} 

Also, using async/await,

async function convertPdfToImage(fileName) {
  let pdfImage = new PDFImage(fileName+".pdf");
  try{
    const imagePaths = await pdfImage.convertFile();
    let file = fs.createWriteStream(imagePaths);
    file.end();
    file.on("finish", () => { resolve(true); });
    file.on("error", reject);
    return true 
  } catch(err){
    console.log(err);
  }
} 

Also, see this question

laxman
  • 1,781
  • 4
  • 14
  • 32
0

The sctructure of your Promises is not really correct, take a look at my example:

const fs = require("fs");

class PDFImage {
  constructor(filename) {
    this.filename = filename;
  }
  convertFile() {
    return new Promise((resolve, reject) => {
      resolve(`image-${this.filename}`);
    });
  }
}

function convertPdfToImage(fileName) {

  return new Promise((resolve, reject) => {

    new PDFImage(fileName).convertFile().then(imageFileName => {

      const file = fs.createWriteStream(imageFileName);
      file.end();

      file.on("error", (error) => {
        reject(error);
      });

      file.on("finish", () => {
        resolve(true)
      });
    });
  });
}

Promise.all([
  convertPdfToImage("first-file"),
  convertPdfToImage("second-file")
]).then(response => {
  console.log(response);
  console.log("files created, can be compared now.");
})

This code will create files image-first-file and image-second-file, and only after both Promises are resolved, print the response and there you can call compareItems.

Titulum
  • 9,928
  • 11
  • 41
  • 79
  • PDFImage is an npm package that I am importing: var PDFImage = require("pdf-image").PDFImage – Afshin Ghazi Feb 27 '20 at 09:21
  • I understood that, but I did not think it would impact the answer. All I need to know is that `PDFImage.convertFile` returns a `Promise`. – Titulum Feb 27 '20 at 09:25