【问题标题】:Execute two promises in sequence in Swift / Combine在 Swift / Combine 中依次执行两个 Promise
【发布时间】:2021-09-28 06:48:08
【问题描述】:

我有两个具有以下签名的函数:

import Combine

func firstCall() -> Future<Result<Void, Error>, Never> {
    return Future { promise in
        promise(.success(.success(())))
    }
}



func secondCall() -> Future<Result<Void, Error>, Never> {
    return Future { promise in
        promise(.success(.success(())))
    }
}


// Execute 1st call, then if it succeeds, execute the 2nd call

如何才能在第一个函数成功完成后才执行第二个函数?

理想情况下,我正在寻找这样的东西:

executeInSequence([firstCall(), secondCall()])
.onResult( { finalResult in
print(finalResult)
})

如果对调用站点有帮助,请随意稍微调整 API 签名。

更多信息:其中一个调用实际上是转换后的同步方法调用,其签名为:

func secondSynchronousCall() throws {
}

    private func secondCall() -> Future<Result<Void, Error>, Never> {
        return Future { [weak self] promise in
            do {
                try self?.secondSynchronousCall()
                promise(.success(.success(())))
            } catch {
                promise(.success(.failure(error)))
            }
        }
    }

【问题讨论】:

  • 你能用Future&lt;Void, Error&gt;代替吗?这将使生活更轻松。
  • 遵循此处的建议:stackoverflow.com/questions/69311371/… 随意重新设计 API 以改用 Future&lt;Void, Error&gt;。我对一般概念而不是特定的函数签名更感兴趣。我添加了一些细节来阐明总体思路以及我的出发点。
  • 你的问题基本上是this,但是Future&lt;Result&lt;Void, Error&gt;, Never&gt;。通过使用这种可怕的类型,您需要编写自己的专用append 运算符,如果结果为failure,则该运算符不会附加。我的建议是,停止使用 Future&lt;Result&lt;Void, Error&gt;, Never&gt;,并使用 LuLuGaGa 上一篇文章中的答案(但使用 Future 扩展名而不是 CurrentValueSubject)。这样你就可以使用内置的append
  • 是的,好主意。可怕的类型虽然看起来很擅长呼叫站点,但会导致太多问题。

标签: swift promise functional-programming combine


【解决方案1】:

在 Combine 中,Futures 只是专门的发布者。如果你与出版商打交道,你会做这样的事情:

let cancellable = firstCall()
.tryMap { result in
    try result.get()
}
.flatMap { _ in
    secondCall()
}
.tryMap { result in
    try result.get()
}
.sink { completion in
    print(completion)
} receiveValue: { _ in
    print("reveiveValue")
}

您可以更简洁地编写它,但是,我建议先简化您的输出和错误类型,正如 cmets 中已经指出的那样:

例如:

func firstCall2() -> Future<Void, Error> {
    return Future { promise in
        promise(.success(()))
        //promise(.failure(MyError()))
    }
}

func secondCall2() -> Future<Void, Error> {
    return Future { promise in
        promise(.success(()))
    }
}

然后:

let cancellable2 = firstCall2()
.map(secondCall2)
.sink { completion in
    print(completion)
} receiveValue: { _ in
    print("reveiveValue")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 2018-11-09
    • 1970-01-01
    • 2020-12-10
    相关资源
    最近更新 更多