You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对两个合并的Publisher应用compactMap操作符?

Combine:仅当两个Publisher均输出非nil值时触发Sink

我们有以下两个发布者:

var firstFeed = PassthroughSubject<Int?, Never>()
var secondFeed = PassthroughSubject<Int?, Never>()

需求是创建一个订阅,只有当两个发布者都输出非nil值时,才调用sink处理数据。

当前实现

目前的实现方式是先分别对两个发布者做compactMap过滤nil,再合并:

let sub = firstFeed
    .compactMap{$0}
    .combineLatest(secondFeed.compactMap({$0}))
    .sink { firstValue, secondValue in
        print("we sunk with \(firstValue), \(secondValue)")
    }

测试数据流

我们输入以下测试数据:

firstFeed.send(1)
secondFeed.send(nil)
secondFeed.send(2)
firstFeed.send(nil)
firstFeed.send(3)
firstFeed.send(nil)
secondFeed.send(nil)
firstFeed.send(nil)
secondFeed.send(nil)
secondFeed.send(4)
firstFeed.send(nil)
secondFeed.send(nil)
firstFeed.send(5)
secondFeed.send(6)
secondFeed.send(nil)
firstFeed.send(nil)
firstFeed.send(7)
firstFeed.send(nil)
secondFeed.send(8)

当前输出

执行后得到符合预期的输出:

we sunk with 1, 2
we sunk with 3, 2
we sunk with 3, 4
we sunk with 5, 4
we sunk with 5, 6
we sunk with 7, 6
we sunk with 7, 8

期望写法

希望能先合并两个发布者,再通过一次compactMap过滤掉包含nil的组合,但不知道compactMap的闭包该如何编写:

let sub = firstFeed
    .combineLatest(secondFeed)
    .compactMap{?}
    .sink { firstValue, secondValue in
        print("we sunk with \(firstValue), \(secondValue)")
    }

解决方案

可以在compactMap中对两个值同时进行非nil判断,只有当两者都有效时返回元组,否则返回nil,以此过滤掉无效组合。

标准写法

let sub = firstFeed
    .combineLatest(secondFeed)
    .compactMap { first, second in
        guard let first = first, let second = second else {
            return nil
        }
        return (first, second)
    }
    .sink { firstValue, secondValue in
        print("we sunk with \(firstValue), \(secondValue)")
    }

简洁写法

利用Swift的类型转换特性,将(Int?, Int?)类型的元组尝试转型为(Int, Int),转型失败时返回nil,从而被compactMap过滤:

let sub = firstFeed
    .combineLatest(secondFeed)
    .compactMap { $0 as? (Int, Int) }
    .sink { firstValue, secondValue in
        print("we sunk with \(firstValue), \(secondValue)")
    }

两种写法的执行效果和原实现完全一致,都能得到预期的输出。

内容的提问来源于stack exchange,提问作者Reza Shirazian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:50:10