合并:如何在不完成原始发布者的情况下替换/捕获错误? [英] Combine: how to replace/catch an error without completing the original publisher?

查看:69
本文介绍了合并:如何在不完成原始发布者的情况下替换/捕获错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码:

    enum MyError: Error {
        case someError
    }

    myButton.publisher(for: .touchUpInside).tryMap({ _ in
        if Bool.random() {
            throw MyError.someError
        } else {
            return "we're in the else case"
        }
    })
        .replaceError(with: "replaced Error")
        .sink(receiveCompletion: { (completed) in
            print(completed)
        }, receiveValue: { (sadf) in
            print(sadf)
        }).store(in: &cancellables)

每当我点击按钮时,都会得到we're in the else case,直到Bool.random()为真-现在会引发错误.我尝试了不同的方法,但无法捕获/替换/忽略错误,只是在点击按钮后继续操作.

Whenever I tap the button, I get we're in the else case until Bool.random() is true - now an error is thrown. I tried different things, but I couldn't achieve to catch/replace/ignore the error and just continue after tapping the button.

在代码示例中,我希望拥有例如以下输出

In the code example I would love to have e.g. the following output

we're in the else case
we're in the else case
replaced Error
we're in the else case
...

相反,我在replaced error之后得到了finished,并且没有发出任何事件.

instead I get finished after the replaced error and no events are emitted.

修改 给定具有AnyPublisher<String, Error>的发布者,如何在发生错误时不完成而将其转换为AnyPublisher<String, Never>,即忽略原始发布者发出的错误?

Edit Given a publisher with AnyPublisher<String, Error>, how can I transform it to a AnyPublisher<String, Never> without completing when an error occurs, i.e. ignore errors emitted by the original publisher?

推荐答案

我相信E. Coms的回答是正确的,但我会说它要简单得多.处理错误而不导致管道在发生错误后停止处理值的关键是将错误处理发布者嵌套在flatMap:

I believe E. Coms answer is correct, but I'll state it much simpler. The key to handling errors without causing the pipeline to stop processing values after an error is to nest your error-handling publisher inside of flatMap:

import UIKit
import Combine

enum MyError: Error {
  case someError
}

let cancel = [1,2,3]
  .publisher
  .flatMap { value in
    Just(value)
      .tryMap { value throws -> Int in
        if value == 2 { throw MyError.someError }
        return value
    }
    .replaceError(with: 666)
  }
  .sink(receiveCompletion: { (completed) in
    print(completed)
  }, receiveValue: { (sadf) in
    print(sadf)
  })

输出:

1
666
3
finished

您可以在操场上运行此示例.

You can run this example in a playground.

关于OP的

编辑对于具有AnyPublisher<String, Error>的发布者,如何在发生错误时将其转换为AnyPublisher<String, Never>而没有完成,即忽略原始发布者发出的错误?

Edit Given a publisher with AnyPublisher<String, Error>, how can I transform it to a AnyPublisher<String, Never> without completing when an error occurs, i.e. ignore errors emitted by the original publisher?

你不能.

这篇关于合并:如何在不完成原始发布者的情况下替换/捕获错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆