通过请求流和异步处理关闭了连接

时间:2020-02-21 15:33:23

标签: node.js express stream

我在处理来自HTTP请求的流时遇到问题。处理程序从流中收集数据,并在发送响应之前执行一些异步操作。

一旦收集了流数据,就在调用someAsyncStuff之前关闭HTTP连接。

这是一个重现此问题的示例。我在做什么错了?

import * as Busboy from 'busboy'
import * as express from 'express'
import { pipeline } from 'stream'
import concat = require('concat-stream')

const app = express()

app.post('/', (req, res) => {
  const busboy = new Busboy({ headers: req.headers })

  busboy.on('file', (_, file) => {
    pipeline(
      file,
      concat(buffer =>
        someAsyncStuff(buffer.toString())
          .then(length => res.send({ length }))
          .catch(err => res.status(500).send(err.message))
      ),
      err => {
        if (err) res.status(500).send(err.message)
      }
    )
  })

  pipeline(req, busboy, err => {
    if (err) res.status(500).send(err.message)
  })
})

function someAsyncStuff(s: string): Promise<number> {
  return new Promise(resolve => setTimeout(() => resolve(s.length), 1))
}

app.listen('3000')

1 个答案:

答案 0 :(得分:2)

使用req.pipe似乎有效。

import Busboy from 'busboy'
import express from 'express'
import { pipeline } from 'stream'
import concat from 'concat-stream'

const app = express()

app.post('/', (req, res) => {
  const busboy = new Busboy({ headers: req.headers })

  busboy.on('file', (_, file) => {
    pipeline(
      file,
      concat(buffer =>
        someAsyncStuff(buffer.toString())
          .then(length => res.json({ length }))
          .catch(err => res.status(500).send(err.message))
      ),
      err => {
        if (err) res.status(500).send(err.message)
      }
    )
  })
  req.pipe(busboy);
})

function someAsyncStuff(s) {
  return new Promise(resolve => setTimeout(() => resolve(s.length), 1000))
}

app.listen('3000')