如何在Highland流中处理Promise拒绝并忽略失败的Promise?
处理Highland.js中Promise拒绝的正确姿势
你遇到的问题是Highland.js的典型行为:当流中的Promise被拒绝时,如果没有捕获对应的错误事件,流会直接崩溃抛出未处理的错误。要实现只保留成功的Promise结果、忽略失败项的需求,不需要先把拒绝转为null再过滤,直接用Highland的错误处理API就能搞定,下面是两种最常用的方案:
方案1:为每个Promise子流单独处理错误
在创建每个Promise对应的Highland子流时,就捕获它的错误并返回空流(相当于直接忽略这个失败的Promise):
import * as highland from "highland"; import * as lodash from "lodash/fp"; const range = lodash.range(0, 10); const createPromise = async (i: number): Promise<number> => { if (i % 2 !== 0) { return Promise.resolve(i); } return Promise.reject("Some rejection message"); }; highland(range) .map((i) => { // 捕获当前Promise子流的错误,返回空流来忽略失败结果 return highland(createPromise(i)).errors(() => highland([])); }) .flatten() .toArray((items) => console.log(items)); // 输出: [ 1, 3, 5, 7, 9 ]
这种方式的好处是错误处理粒度更细,你还可以在errors的回调里记录错误日志:
.errors((err) => { console.error(`处理数字${i}时Promise失败:`, err); return highland([]); })
方案2:在主流上统一捕获所有错误
如果所有失败的Promise都需要被忽略,也可以在主流上使用errors操作符统一处理,这样不需要修改每个子流的创建逻辑:
highland(range) .map((i) => highland(createPromise(i))) .flatten() // 统一捕获流中所有错误,用空流替代错误项 .errors(() => highland([])) .toArray((items) => console.log(items));
为什么原来的代码会崩溃?
Highland的流基于Node.js的EventEmitter实现,当流中出现未被捕获的error事件时,就会像未处理的Promise拒绝一样,直接抛出错误终止进程。errors操作符的作用就是捕获这些错误事件,并用你返回的流继续处理,避免流崩溃。
兜底:监听全局流错误(可选)
如果担心还有未被errors捕获的意外错误,可以给整个流添加error事件监听作为兜底:
const stream = highland(range) .map((i) => highland(createPromise(i))) .flatten() .errors(() => highland([])) .toArray((items) => console.log(items)); // 兜底处理未捕获的错误 stream.on("error", (err) => { console.error("流发生未预期错误:", err); });
内容的提问来源于stack exchange,提问作者k0pernikus
相关产品推荐
相关产品推荐

