簡體   English   中英

.then()似乎沒有在等待上一個.then()

[英].then() does not appear to be waiting for the previous .then()

我正在創建一個將多個markdown文件轉換為一個pdf的過程。 它為在源目錄中找到的每個.md文件創建一個pdf文件。 然后將各個pdf文件合並為一個pdf。 這是最后一步,無法說出單獨的pdf文件不存在。

const markdownpdf = require('markdown-pdf')
const path = require('path')
const PDFMerge = require('pdf-merge')
const fse = require('fs-extra')

const srcDir = '../manuscript'
const outDir = 'out'

const main = () => {

    fse.pathExists(outDir)
    .then(() => {
      fse.remove(outDir).then(() => {
        fse.ensureDir(outDir)
      }).then(() => {
        return fse.readdir(srcDir)
      }).then((srcDirFiles) => {
        console.log('source directory file count = ', srcDirFiles.length)
        return srcDirFiles.filter(f => path.extname(f) === '.md')
      }).then((mdFiles) => {
        console.log('number of md files', mdFiles.length);
        return mdFiles.map(file => {

          const outFileName = `${path.basename(file, '.md')}.pdf`
          fse.createReadStream(`${srcDir}/${file}`)
            .pipe(markdownpdf())
            .pipe(fse.createWriteStream(`${outDir}/${outFileName}`))
          return `${outDir}/${outFileName}`
        })
      }).then(outFiles => {
        console.log('number of pdf files created =', outFiles.length)
        PDFMerge(outFiles, { output: `${__dirname}/3.pdf`  })
      })
    })
}

main()

如果我將PDFMerge()行包裝在setTimeout()中,則可以正常工作

setTimeout(() => {
  PDFMerge(outFiles, { output: `${__dirname}/3.pdf` })
}, 1000)

我想知道為什么需要setTimeout()以及需要更改什么,所以不需要。

我還編寫了一個具有相同問題的異步/等待版本,並且還使用了setTimeOut()

編輯

為了回應Zach Holt的建議,以下是async / await版本:

const markdownpdf = require('markdown-pdf')
const path = require('path')
const PDFMerge = require('pdf-merge')
const fse = require('fs-extra')

const srcDir = '../manuscript'
const outDir = 'out'

const createPdf = async (file) => {
  try {
    const outFileName = `${path.basename(file, '.md')}.pdf`
    await fse.createReadStream(`${srcDir}/${file}`)
      .pipe(markdownpdf())
      .pipe(await fse.createWriteStream(`${outDir}/${outFileName}`))
  }
  catch (e) {
    console.log(e)
  }
}

const makePdfFiles = (files) => {
  files.forEach(file => {
    if (path.extname(file) === '.md') {
      createPdf(file)
    }
  })
}

const mergeFiles = async (files) => {
  try {
    await PDFMerge(files, {output: `${__dirname}/3.pdf`})
  }
  catch (e) {
    console.log(e)

  }
}

const addPathToPdfFiles = (files) => {
  return files.map(file => {
    return `${outDir}/${file}`
  })
}

const main = async () => {
  try {
    const exists = await fse.pathExists(outDir)
    if (exists) {
      await fse.remove(outDir)
    }
    await fse.ensureDir(outDir)
    const mdFiles = await fse.readdir(srcDir)
    const filesMade = await makePdfFiles(mdFiles)
    const pdfFiles = await fse.readdir(outDir)
    const pdfFilesWithPath = addPathToPdfFiles(pdfFiles)
    mergeFiles(pdfFilesWithPath)
    // setTimeout(() => {
    //   mergeFiles(pdfFilesWithPath)
    // }, 1000)
  } catch (e) {
    console.log(e)
  }
}

它有同樣的問題。

我也嘗試過:

const makePdfFiles = files => {
  return new Promise((resolve, reject) => {
    try {
      files.forEach(file => {
        if (path.extname(file) === '.md') {
          createPdf(file)
        }
      })
      resolve(true)
    } catch (e) {
      reject(false)
      console.log('makePdfFiles ERROR', e)
    }
  })
}

但這沒什么區別。

您需要從ensureDir()返回promise以使其等待。

我認為問題可能在於您正在為每個.md文件創建一個讀取流,但沒有等待讀取完成再嘗試合並outFiles。

您可能要等到outFiles長度與合並前找到的md文件數相同。

另外,您應該為此堅持異步/等待。 它將使代碼更加清晰

讓我過分簡化您的代碼以說明問題:

p1.then(() => {
  p2.then().then().then()
}).then(/* ??? */)

與以下內容相同:

p1.then(() => {
  p2.then().then().then()
  return undefined
}).then(/* undefined */)


鏈接所需的是返回內部的Promise

 p1.then(() => // no {code block} here, just return value p2.then().then().then() ).then(/* ??? */) 

與以下內容相同:

 p1.then(() => { p3 = p2.then() p4 = p3.then() p5 = p4.then() return p5 }).then(/* p5 */) 

據我所知,最初的問題是方法,而不是其他人正確指出的明顯錯誤。 我發現了一個從多個md文件生成一個pdf的總體目標的簡單得多的解決方案。

const markdownpdf = require('markdown-pdf')
const path = require('path')
const fse = require('fs-extra')

const srcDir = '../manuscript'

const filterAndAddPath = (files) => {
  try {
    const mdFiles = files
      .filter(f => path.extname(f) === '.md')
      .map(f => `${srcDir}/${f}`)
    return mdFiles
  }
  catch (e) {
    console.log('filterAndAddPath', e)

  }
}

const main4 = async ()  => {
  const allFiles = await fse.readdir(srcDir)
  const mdFiles = filterAndAddPath(allFiles)
  const bookPath = 'book.pdf'
  markdownpdf()
    .concat.from(mdFiles)
    .to(bookPath, function() {
      console.log('Created', bookPath)
    })
}

main4()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM