将读取流传送到响应中使其成为一次性使用

问题描述

现在,我正在尝试使用Node读取流和流转换来编辑我的HTML数据,然后再将其发送到客户端。是的,我知道模板引擎存在,尽管这是我现在正在使用的方法。我正在使用的代码如下:

const express = require('express')
const app = express()
const port = 8080
const fs = require('fs')
const Transform = require("stream").Transform
const parser = new Transform()
const newLinestream = require("new-line")

parser._transform = function(data,encoding,done) {
    const str = data.toString().replace('</body>',`<script>var questions = ${JSON.stringify(require('./questions.json'))};</script></body>`)
    this.push(str)
    done()
}

app.get('/',(req,res) => {
    console.log('Homepage served')
    res.write('<!-- Begin stream -->\n');
    let stream = fs.createReadStream('./index.html')
    stream.pipe(newLinestream())
    .pipe(parser)
    .on('end',() => {
        res.write('\n<!-- End stream -->')
    }).pipe(res)
})

这只是尝试使此方法起作用的粗略草稿。现在,我遇到的问题是,我第一次加载网页时一切正常,但是每次之后,我得到的html如下所示:

<!-- Begin stream -->
<html>
  <head></head>
  <body></body>
</html>

似乎流被挂在中间了,因为大多数数据从未传输过,流也从未结束。我在控制台中注意到的另一件事是,在10次重载后,[Transform]上有11个事件侦听器发出警告,并且可能发生内存泄漏。我试图在读取流结束后清除读取流和解析器上的所有事件侦听器,但这并不能解决任何问题。有没有办法更改我的代码解决此问题?

Original StackOverflow post that this method came from

解决方法

这里的问题是使用单个解析器和._transform()而不是每次应用程序收到请求时都创建新的转换。将const parser = ...parser._transform = ...放在app.get()内可以解决所有问题。