Swift Combine 接收器在第一次错误后停止接收值 [英] Swift Combine sink stops receiving values after first error

查看:22
本文介绍了Swift Combine 接收器在第一次错误后停止接收值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将我的项目从 RxSwift 迁移到 Combine我有一个逻辑,我希望发布者每次单击按钮时都发出事件.实际点击按钮执行pushMe.send()

Im moving my project to Combine from RxSwift I have a logic where I want publisher to emit event every time I click button. Acrually clicking button executed pushMe.send()

pushMe
            .print("Debug")
            .flatMap { (res) -> AnyPublisher<Bool, Error> in
                return Future<Bool, Error>.init { closure in
                    closure(.failure(Errors.validationFail))
                }.eraseToAnyPublisher()
            }
            .sink(receiveCompletion: { completion in
                print("Completion received")
            }, receiveValue: { value in
                print("Value = (value)")
            })
            .store(in: &subscriptions)

控制台结果

Debug: receive value: (true)
Completion received
Debug: receive value: (true)
Debug: receive value: (true)

我不明白为什么接收器只在第一个事件上收到错误.其余点击将被忽略.

I do not understand why sink receive error only on first event. The rest clicks are ignored.

推荐答案

flatMap 是做什么的 -

  1. 订阅给定的发布者(比如 XPublisher).
  2. 发送发出的错误和输出值(未完成的事件/完成)由 XPublisher 传输到下游.

因此,如果您在 flatMap 内部处理错误(这意味着 flatMap 内部的发布者不会发出错误),则 flatMap 从不向下游发送错误.

So If you handle errors inside the flat map , (which means the publisher inside the flatMap does not emit errors), then flatMap Never sends an error to the down stream.

pushMe
    .print("Debug")
    .flatMap { (res) -> AnyPublisher<Bool, Never> in //<= here
        return Future<Bool, Error>.init { closure in
            closure(.failure(Errors.validationFail))
        }
        .replaceError(with: false) //<= here
        .eraseToAnyPublisher()
    }
    .sink(receiveCompletion: { completion in
        print("Completion received")
    }, receiveValue: { value in
        print("Value = (value)")
    })
    .store(in: &subscriptions)

否则你可以在 fatMap 之外处理错误.这里的问题是,一旦出现错误,订阅/可取消就会被取消.(在下面的示例中,错误已替换为 false 值)

Otherwise you can handle error outside the fatMap. Problem here is that, once an error out whole the subscription / cancellable cancelled. ( in the below example error has replace with a false value)

pushMe
    .print("Debug")
    .flatMap { (res) -> AnyPublisher<Bool, Error> in 
        return Future<Bool, Error>.init { closure in
            closure(.failure(Errors.validationFail))
        }
        .eraseToAnyPublisher()
    }
    .replaceError(with: false) //<= here
    .sink(receiveCompletion: { completion in
        print("Completion received")
    }, receiveValue: { value in
        print("Value = (value)")
    })
    .store(in: &subscriptions)

上面代码中发生了什么.

What is happening in the above code.

  1. FlatMap error 输出.
  2. 将错误替换为 false(因此将收到一个 false 值)
  3. 订阅因流中的错误而取消.

这篇关于Swift Combine 接收器在第一次错误后停止接收值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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