【发布时间】:2022-02-27 04:35:46
【问题描述】:
我想创建一个简单的 csv 解析器(使用 csv 模块)并在文件不存在时处理错误。
如果我注释掉 sleep 方法,代码会到达 finally(并写出一些错误)。
我错过了什么?在我的真实示例中,我确实需要在那里完成一些等待的任务。
import fs from 'fs';
import * as csv from 'csv';
import { finished } from 'stream';
type TabularFileType = 'csv' | 'tsv';
const DELIMITER_BY_TYPE: Record<TabularFileType, string> = {
csv: ',',
tsv: '\t',
};
/**
* Creates an (async) iterable from a tabular file at `path`
* @param type type of file, could be `'csv'` or `'tsv'`
* @param path path of the file to be loaded
* @param columns an array of string defining the property names of the columns
* @param options can specify some optional things,
* like encoding (will decode using iconv-lite)
* and skip some header lines (with the help of `fromLines`)
*/
export function tabularStream<T>(
type: TabularFileType,
path: string,
columns: string[],
options?: { encoding?: string; fromLine?: number }
): csv.parser.Parser {
console.info('About to read file from "%s"', path);
const stream = fs.createReadStream(path);
const result = stream.pipe(
csv.parse({
delimiter: DELIMITER_BY_TYPE[type],
fromLine: options?.fromLine,
columns,
})
);
finished(stream, (err) => {
if (err) {
result.destroy(new Error('whoops'));
}
});
console.log("About to return");
return result;
}
const sleep = (millis: number) => new Promise(resolve => setTimeout(resolve, millis));
(async () => {
console.log('wait a bit');
await sleep(100);
console.log('waited');
const p = tabularStream('csv', 'nonexistent', []);
// If you comment it out, ended will appear on output
await sleep(100);
console.log('after sleep') ;
try {
for await(const record of p) {
console.log('Got a record', record);
}
} catch (e) {
console.log('Some error!', e);
} finally {
console.log('Finally!');
}
})();
【问题讨论】:
-
我无法重现任何问题。使用 ts-node v10.2.1 和 node v16.13.0。但我建议将对
tabularStream的调用放在try块内。 -
是否可以提供 .csv 文件的摘录作为要点,以便问题可重现?
-
@jorgenkg: 不存在:所以没有这样的文件。代码完成。
-
由于
stream变量缺少"error"侦听器,因此代码中断。该错误不会传播到随后的管道流中间件。但是,可以将代码重构为使用stream.pipeline(),它隐式地同时管道数据和处理错误。 -
@jorgenkg 为什么不将您的评论转换为答案?
标签: node.js typescript csv stream