【发布时间】:2017-09-18 14:10:22
【问题描述】:
我尝试用highland.js编写一个程序来下载几个文件,解压缩并解析成对象,然后通过flatMap将对象流合并为一个流并打印出来。
function download(url) {
return _(request(url))
.through(zlib.createGunzip())
.errors((err) => console.log('Error in gunzip', err))
.through(toObjParser)
.errors((err) => console.log('Error in OsmToObj', err));
}
const urlList = ['url_1', 'url_2', 'url_3'];
_(urlList)
.flatMap(download)
.each(console.log);
当所有 URL 都有效时,它可以正常工作。如果 URL 无效且没有下载文件,则 gunzip 报告错误。我怀疑发生错误时流会关闭。我希望flatMap 将继续使用其他流,但是程序不会下载其他文件并且没有打印任何内容。
处理流错误的正确方法是什么?如何使flatMap在一个流出现错误后不停止?
在命令式编程中,我可以添加调试日志来跟踪错误发生的位置。如何调试流式代码?
PS。 toObjParser 是一个节点转换流。它采用可读的 OSM XML 流并输出与 Overpass OSM JSON 兼容的对象流。见https://www.npmjs.com/package/osm2obj
2017-12-19 更新:
我尝试按照@amsross 的建议在errors 中调用push。为了验证push 是否真的有效,我推送了一个 XML 文档,它被以下解析器解析,我从输出中看到了它。但是,stream 仍然停止并且 url_3 没有下载。
function download(url) {
console.log('download', url);
return _(request(url))
.through(zlib.createGunzip())
.errors((err, push) => {
console.log('Error in gunzip', err);
push(null, Buffer.from(`<?xml version='1.0' encoding='UTF-8'?>
<osmChange version="0.6">
<delete>
<node id="1" version="2" timestamp="2008-10-15T10:06:55Z" uid="5553" user="foo" changeset="1" lat="30.2719406" lon="120.1663723"/>
</delete>
</osmChange>`));
})
.through(new OsmToObj())
.errors((err) => console.log('Error in OsmToObj', err));
}
const urlList = ['url_1_correct', 'url_2_wrong', 'url_3_correct'];
_(urlList)
.flatMap(download)
.each(console.log);
【问题讨论】:
标签: javascript node.js stream highland.js