Home > database >  Promise function doesn't trigger after another promise
Promise function doesn't trigger after another promise

Time:09-15

I'm working on a microcontroller that would either take docx files or html strings in input and would transform it into a singular pdf file and return its link as an ouput.

My code looks like this so far:

// 'files' is an array of uploaded docx files.
const uploaded = files.map((file) => {
    return new Promise((resolve, reject) => {
        pump(
            file.toBuffer(),
            fs.createWriteStream(join(__dirname, 'files', file.filename))
                .on('finish', resolve)
          )
     })
})

Promise.all(uploaded)
    // Is triggered
    .then(async () => await convertFiles())
    // Is not triggered
    .then(async () => {
        // concatStoreFiles() is an external function because I need it somewhere else too
        test = await concatStoreFiles(join(__dirname, 'files'))
        console.log({test})
        res.send(test)
    })


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

        const cmd = `soffice --headless --convert-to pdf --outdir ${join(__dirname, 'files')} ${join(__dirname, 'files', '*.*')}`
        exec(cmd, (error, stdout, stderror) => {
            if (error) console.warn(error)

            resolve(stdout ?? stderror)
        })
    })
}

concatStoreFile.js

module.exports = async function concatFiles (dirPath, outPath) {
    return new Promise ((resolve, reject) => {
        const existingFiles = []
        fs.readdir(dirPath, (e, files) => {
            files.forEach((file) => {
                // is added to the files list only if finishing with ".pdf"
                if (/[\d\w_-] .pdf/.matches(file)) {
                    existingFiles.push(file)
                }
            });

            resolve(existingFiles)
       })
    })
}

I'm working with Insomnia for my development / test process, and it tells me that I get an empty response. However, I'm supposed to get an array of pdf files existing in a specific directory. I'm not even getting console.log({test}), so I don't think my second then() is triggered.

I'm really rusty with async / await and Promise syntaxes, what should I do in this situation?

Thank you in advance

CodePudding user response:

The @fastify/multipart's toBuffer() API returns a Promise, not a buffer. Checkout this article

So you need to write something like:

const uploaded = files.map(processFile)

async function processFile (file) {
  const buffer = await file.toBuffer()
  const storedFileName = join(__dirname, 'files', file.filename)
  const writeStream = fs.createWriteStream(storedFileName)
  return new Promise((resolve, reject) => {
    pump(buffer, writeStream, (err) => {
      if(err) { return reject(err) }
      resolve(storedFileName)
    })
  }
}

Moreover, to improve the code, I returned the storedFileName instead of recalculating it.

You can convert this:

.then(async () => await convertFiles())

to this:

.then(() => convertFiles())

Mixing async/await and promise then/catch leads to hidden bugs hard to find

  • Related