swift - 创建一个未完成发布者的捕获/替换错误对应项?
问题描述
我正在努力处理 Combine 中的错误,发现捕获或替换错误完成并结束发布者非常违反直觉。例如,即使我处理了异常,这也会结束发布者:
Just([1, 2, 3, NaN, 5, 6])
.tryMap { _ in throw DummyError() }
.catch { _ in Just(4) } // or .replaceError(with: 4)
.sink { print($0) } // <-- ends at 4 and ignores 5, 6, and anything ever again
如果发布者订阅了某些系统更改,第一个错误将使我的应用程序死机,直到用户重新启动应用程序。我想创建一个catch
不会结束发布者的对应项。我知道flatMap
它被用于此,但这会产生另一个复杂的维度,例如反转内部/外部发布者、发布者无限复制、背压等。
有没有办法做这样的事情:
Just([1, 2, 3, NaN, 5, 6])
.tryMap { _ in throw DummyError() }
.ignoreError { error in
log("Error occurred: \(error)")
}
.sink { print($0) } // 1, 2, 3, 5, 6
如何将此意图封装在一个简单的自定义链命令中ignoreError
,并让我的发布者继续存在?
解决方案
完成管道的错误是发布者和订阅者工作合同的一部分。这是有道理的。如果上游发布者抛出错误并且不知道如何自行恢复,则基本完成。这与抛出错误的函数没有什么不同。
在您的示例中,tryMap
抛出一个错误,虽然下游喜欢replaceError
可以转换其下游的错误,但它不期望来自其上游的更多值,所以它也完成了。
flatMap
将管道的其余部分与抛出错误的发布者隔离开来。换句话说,上游flatMap
不会抛出错误,并且flatMap
自身也不会抛出错误,因为返回的内部发布者(带有Just
//的管道tryMap
)catch
会处理错误。
Just([1, 2, 3, 5, 6])
.flatMap {
Just($0)
.tryMap { _ in throw DummyError() }
.catch { _ in Just(4) }
}
.sink { print($0) }
推荐阅读
- javascript - 如何使用 JavaScript 将对象转换为数组格式
- javascript - 如何在threejs中获得三视图绘图?
- json - 根据值中的特定元素对键进行排序
- javascript - 包裹。添加链接后样式消失
- excel - 一个使用 INDEX、SMALL、IF 的数组函数有效,但另一个无效
- ios - 如何快速设置 PLCrashReporter.setCrashCallbacks?
- javascript - 如何将 date-fns 中的 startOfDay 与时区一起使用?
- android - 在 android 中使用 5 到 7 天后,ionic 5 应用程序崩溃
- angular - 使用 dockerfile.test 在 jenkins 中启用 sonarQube - ChromeHeadless 在 2000 毫秒内没有被 SIGKILL 杀死,继续
- javascript - 在每次出现日期格式 yyyy-mm-dd 时拆分字符串