[英]"Failed to pipe. The response has been emitted already" when reading a stream (nodejs)
So my code is supposed to read some lines from a CSV file, convert them to an array of JSON objects, and return that array.所以我的代码应该从 CSV 文件中读取一些行,将它们转换为 JSON 对象数组,然后返回该数组。 To read the file as a stream, I am using got
, and then using it in fast-csv
.要将文件读取为 stream,我使用got
,然后在fast-csv
中使用它。 In order to return the resulting array, I put the entire thing into a Promise like this:为了返回结果数组,我将整个内容放入 Promise 中,如下所示:
async GetPage() : Promise<{OutputArray:any[], StartingIndex:number}>{
return new Promise(async (resolve, reject) => {
const output:any[] = [];
const startingIndex = this.currentLocation;
try{
parseStream(this.source, {headers:true, maxRows:this.maxArrayLength, skipRows:this.currentLocation, ignoreEmpty:true, delimiter:this.delimiter})
.on('error', error => console.log(`parseStream: ${error}`))
.on('data', row => {
const obj = this.unflatten(row); // data is flattened JSON, need to unflatten it
output.push(obj); // append to output array
this.currentLocation++;
})
.on('end', (rowCount: number) => {
console.log(`Parsed ${this.currentLocation} rows`);
resolve({OutputArray:output, StartingIndex:startingIndex});
});
}
catch(ex){
console.log(`parseStream: ${ex}`);
throw new Error(ex);
}
})
}
Now when I call this once ( await GetPage()
) it works perfectly fine.现在,当我调用它一次( await GetPage()
)时,它工作得非常好。 The problem is when I'm calling it a second time in a row.问题是当我连续第二次调用它时。 I'm getting the following:我得到以下信息:
UnhandledPromiseRejectionWarning: Error: Failed to pipe. The response has been emitted already.
I've seen a similar case over here: https://github.com/sindresorhus/file-type/issues/342 but from what I gather this is a different case, or rather if it's the same I don't know how to apply the solution here.我在这里看到了一个类似的案例: https://github.com/sindresorhus/file-type/issues/342但据我所知,这是一个不同的案例,或者更确切地说,如果它是相同的,我不知道如何在此处应用解决方案。
The GetPage
is a method inside a class CSVStreamParser
which is given a Readable
in the constructor, and I create that Readable like this: readable:Readable = got.stream(url)
GetPage
是 class CSVStreamParser
中的一个方法,它在构造函数中被赋予一个Readable
,我像这样创建 Readable: readable:Readable = got.stream(url)
What confuses me is that my first version of GetPage did not include a Promise, but rather accepted a callback (I just sent console.log
to test it) and when I called it several times in a row there was no error, but it could not return a value so I converted it to a Promise.让我困惑的是,我的第一个版本的 GetPage 没有包含 Promise,而是接受了一个回调(我只是发送了console.log
来测试它),当我连续调用它几次时没有错误,但它可以不返回值,所以我将其转换为 Promise。
Thank you: :)谢谢: :)
First, remove both of the async
, since you are already returning a Promise
.首先,删除两个async
,因为您已经返回Promise
。
Then remove the try/catch
block and throw
since you shouldn't throw in a promise.然后删除try/catch
块并throw
,因为您不应该抛出 promise。 Instead use the reject
function.而是使用reject
function。
GetPage() : Promise<{OutputArray:any[], StartingIndex:number}>{
return new Promise((resolve, reject) => {
const output:any[] = [];
const startingIndex = this.currentLocation;
parseStream(this.source, {headers:true, maxRows:this.maxArrayLength, skipRows:this.currentLocation, ignoreEmpty:true, delimiter:this.delimiter})
.on('error', error => reject(error))
.on('data', row => {
const obj = this.unflatten(row); // data is flattened JSON, need to unflatten it
output.push(obj); // append to output array
this.currentLocation++;
})
.on('end', (rowCount: number) => {
console.log(`Parsed ${this.currentLocation} rows`);
resolve({OutputArray:output, StartingIndex:startingIndex});
});
});
}
Here's some resources to help you learn about async functions and promises .这里有一些资源可以帮助您了解异步函数和承诺。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.