美文网首页
Combine -- 响应式和指令式的桥梁

Combine -- 响应式和指令式的桥梁

作者: jancywen | 来源:发表于2021-02-23 10:18 被阅读0次

    Apple 平台的开发,包括系统级别的 API 和大多数的第三方框架,也都是按照指令式编程的方式来编写的。想要在 Combine 的响应式框架中使用这些指令式的 API,我们需要一些手段来把这些命令转换为合适的 Publisher。

    Future

    如果订阅和值的发布是同步过程,我们可以直接用Just 将某个值 “包装” 成一个 Publisher 来提供给各类 Publisher 的合并操作
    如果我们希望订阅操作和值的发布是异步行为,不在同一时间发生的话,可以使用 Future。Future 提供了一种方式,可以让我们创建一个接受未来的事件的 Publisher。

    struct SampleModel {
        var id: Int?
    }
    
    func sampleRequestAction(handler: @escaping(SampleModel?, Error?) -> Void) {
        print("模拟延时")
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
            print("延时结束返回")
            handler(SampleModel(id: 5), nil)
        }
    }
    
    Future<SampleModel, Error> { promise in
        sampleRequestAction { (model, err) in
            print("promise")
            if let model = model {
                promise(.success(model))
            }else {
                promise(.failure(err!))
            }
        }
    }
    .subscribe(on: RunLoop.main)
    .sink { (complete) in
        print("complete")
        if case .failure(let msg) = complete {
            print(msg)
        }
    } receiveValue: { (model) in
        print("receiveValue:")
        print(model.id)
    }
    
    // 模拟延时
    // 延时结束返回
    // promise
    // receiveValue:
    // Optional(5)
    // complete
    

    Future 只能为我们提供一次性 Publisher:对于提供的 promise,你只有两种选择:发送一个值并让 Publisher 正常结束,或者发送一个错误。因此,Future 只适用于那些必然会产生事件结果,且至多只会产生一个结果的场景。比如刚才看到的网络请求:它要么成功并返回数据及响应,要么直接失败并给出URLError。

    subject

    对于可重复的多次发生的事件,可以使用 subject

    let subject = PassthroughSubject<(), Never>()
    Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
        subject.send()
    }
    

    相关文章

      网友评论

          本文标题:Combine -- 响应式和指令式的桥梁

          本文链接:https://www.haomeiwen.com/subject/mbahfltx.html