【问题标题】:Nestjs stream file dest.on is not a functionNestjs 流文件 dest.on 不是函数
【发布时间】:2020-04-28 06:43:50
【问题描述】:

我尝试使用 nestjs 和 fs 将文件流式传输到 api 响应。这件事很简单,据说可以开箱即用,但我遇到了错误:

_stream_readable.js:638 dest.on('unpipe', onunpipe); TypeError: dest.on 不是函数

import { Controller, HttpCode, HttpStatus, Post, Res } from '@nestjs/common';
import { ApiBearerAuth, ApiInternalServerErrorResponse, ApiOkResponse, ApiTags, 
ApiUnauthorizedResponse } from '@nestjs/swagger';
import { Response } from 'express';
import * as http from 'http';
import { SitemapExportRepository } from './sitemap-export.repository';

const fs = require('fs');

@Controller('api/v1/site-map')
@ApiTags('❤ API > Contents site-map')
export class SitemapExportController {
constructor(private readonly repo: SitemapExportRepository) {}

@Post()
@ApiBearerAuth()
@HttpCode(HttpStatus.OK)
@ApiOkResponse({description: http.STATUS_CODES[200]})
@ApiUnauthorizedResponse({description: http.STATUS_CODES[401]})
@ApiInternalServerErrorResponse({description: http.STATUS_CODES[500]})
async loadContentSupportPublications(@Res() response: Response): Promise<void> {
    const readStream = fs.createReadStream('./dist/test');
    readStream.on('open', () => {
     readStream.pipe(response);
    });

    readStream.on('error', (err: Error) => {
     console.log(err);
    });
 }
}

完整的堆栈跟踪

_stream_readable.js:638
  dest.on('unpipe', onunpipe);
       ^

TypeError: dest.on is not a function
    at ReadStream.Readable.pipe (_stream_readable.js:638:8)
    at ReadStream.readStream.on (/Users/medi/Documents/wkdir/mygit/site-map-api/dist/server.js:9017:32)
    at ReadStream.emit (events.js:189:13)
    at lazyFs.open (internal/fs/streams.js:120:10)
    at FSReqWrap.args [as oncomplete] (fs.js:140:20)

/Users/medi/Documents/wkdir/mygit/site-map-api/node_modules/webpack-shell-plugin/lib/index.js:168
        throw error;
        ^

【问题讨论】:

  • 你解决了吗?
  • 我更改了逻辑,写入内存缓冲区并在 http 响应上流式传输结果。这样 > const buffer = readable({objectMode: true}); buffer._read = () => {}; response.type('application/json').send(buffer);
  • 大吃一惊,虽然我不太明白你为什么需要这样做.. 我想我需要了解更多关于 readable({obectMode}) 的任何想法为什么会这样?如果流是可读的,它应该能够写入可写的 res。与其等待 open 事件,不如直接通过管道处理它。管道将为您处理背压和所有块。没有?
  • 我猜是可读管道流无法处理推送到 http 响应。我正在使用的 webpack 和 nestjs frapmework 的框架或混合的限制。最重要的是,响应通过发送方法比使用流通过响应传递结果更好地流式传输结果

标签: node.js express fs nestjs


【解决方案1】:

通过使用服务写入内存缓冲区并通过 http 响应流式传输结果来找到解决方案。

enter code here
@Post()
@ApiBearerAuth()
@HttpCode(HttpStatus.OK)
@ApiOkResponse({description: http.STATUS_CODES[200]})
@ApiUnauthorizedResponse({description: http.STATUS_CODES[401]})
@ApiInternalServerErrorResponse({description: http.STATUS_CODES[500]})
async loadContentSupportPublications(@Res() response: Response): Promise<void> 
{

 const buffer = readable({objectMode: true});
 buffer._read = () => {};
 response.type('application/json').send(buffer);
 await this.sitemapExportRepository.streamTreeSiteMap(buffer);
}

【讨论】:

  • 这种情况下内存缓冲区可以耗尽吗?即内存不足? '可读'是否意味着在您定义的代码中的某个地方 const { Readable } = require("stream");有趣的是,这也适用于 aws lambda 函数,因为 aws 函数也不喜欢管道。我看到的问题是响应的背压管理无法像处理数据一样快地处理数据。
  • 确实我在做一个 const readable = require('readable-stream').Readable;我在 GAE 服务上运行它,我相信它与 AWS lambda 函数一样。缓冲区是内存,因此可能会用完。您应该调整函数内存的大小以处理负载。我认为不会有背压,因为今天的技术可以很好地处理流式数据
猜你喜欢
  • 2017-02-12
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 2021-12-10
相关资源
最近更新 更多