简体   繁体   English

读取 stream (nodejs) 时,“无法 pipe。响应已经发出”

[英]"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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM