如何确保在文件系统终止写流后Express响应出现?

时间:2019-04-12 18:19:49

标签: javascript node.js asynchronous promise fs

在Express.js API中,我正在创建一个zip文件,该文件存储了一系列PDF文件,这些PDF文件打算以下载的形式传递

我已经使用README文件之后的yazl包创建了zipfile,这很好,当我使用管道创建 createWriteStream 时出现了问题,因为我没有不知道如何正确地等待直到完成。

然后在我的Express路由中,我想发送文件,但是在写流完成之前执行此代码...

这是我的 repository.js 文件中名为 renderReports 的Promise函数的一段代码,在编写PDF文件后,我使用了一个循环将其添加到yazl的zipFile,然后我继续使用fs.createWriteStream

创建zip
const renderFilePromises = renderResults.map((renderedResult, index) =>
  writeFile(`./temporal/validatedPdfs/${invoices[index].id}.pdf`, renderedResult.content)
);
await Promise.all(renderFilePromises);
const zipfile = new yazl.ZipFile();
invoices.map((invoice, index) => {
  zipfile.addFile(`./temporal/validatedPdfs/${invoice.id}.pdf`, `${invoice.id}.pdf`)
});
zipfile.outputStream.pipe(fs.createWriteStream("./temporal/output.zip").on('close', () => {
  console.log('...Done');
}));
zipfile.end();
resolve();

以下代码是我使用诺言的方式

app.post('/pdf-report', async (req, res, next) => {
  const { invoices } = req.body;
  repository.renderReports(reporter, invoices)
    .then(() => {
      res.sendFile('output.zip', {
        root: path.resolve(__dirname, './../../temporal/'),
        dotfiles: 'deny',
      }, (err) => {
      if (err) {
        console.log(err);
        res.status(err.status).end();
      }
      else {
        console.log('Sent:', 'output.zip');
      }
    });
  })
  .catch((renderErr) => {
    console.error(renderErr);
    res.header('Content-Type', 'application/json');
    return res.status(501).send(renderErr.message);
  });
});

我希望有人能解释如何解决这个问题

1 个答案:

答案 0 :(得分:0)

您需要将写流存储在变量中,以便可以访问它。然后,在此变量上,等待流的finish事件。一旦完成写操作,Node.js就会发出此消息。