NestJS中StreamableFile处理数据流后无法返回修改数据的问题
问题分析与解决方案
你遇到的核心问题是异步流事件的回调返回值无法传递到外层函数:addListener('data', ...)是异步触发的回调,里面的return dataValue不会成为normalizeData的返回值,当前代码实际返回的是流对象本身,而非处理后的结果。同时,流的data事件可能触发多次(大文件场景),直接解析单块数据会导致JSON解析错误。
修复后的代码实现
data-manipulation.service.ts
import { Injectable, StreamableFile } from '@nestjs/common'; @Injectable() export class DataManipulationService { async normalizeData(data: StreamableFile): Promise<{ used: number[] }> { return new Promise((resolve, reject) => { const dataChunks: Buffer[] = []; const stream = data.getStream(); // 收集所有流数据块 stream.on('data', (chunk) => { dataChunks.push(chunk); }); // 流读取完成后处理数据 stream.on('end', () => { try { // 拼接所有块并解析为JSON const fullData = JSON.parse(Buffer.concat(dataChunks).toString()); const slicedata = fullData['jsonData'].data; // 提取需要的值并归一化 const values = slicedata.map(element => element[1]); const maxValue = Math.max(...values); // 若需min-max归一化,可替换为 (element - minValue)/(maxValue - minValue) const normalizedValues = values.map(element => element / maxValue); resolve({ used: normalizedValues }); } catch (error) { console.error('数据处理失败', error); reject(error); } }); // 处理流读取错误 stream.on('error', (error) => { console.error('流读取异常', error); reject(error); }); }); } }
finding.controller.ts
@Get('mydata') async testingWithChromium() { const data = this.visualization.loadJsonData( 'src/data/Findingscontroller/mydata.json', ); // 等待异步处理完成后返回结果 return this.dataManipulation.normalizeData(data); }
关键改动说明
- 用Promise封装异步流操作:通过Promise包裹流的
data/end/error事件,确保所有数据接收完成后再进行解析和处理,解决异步回调的返回值传递问题。 - 拼接流数据块:收集所有
data事件的块数据,拼接后再解析JSON,避免大文件分块导致的解析失败。 - 控制器异步等待:控制器方法添加
async/await,等待服务层的Promise完成,将处理后的dataValue正确返回给客户端。
内容的提问来源于stack exchange,提问作者LeSchwambo
相关产品推荐
相关产品推荐

