首页 > 解决方案 > 在 Swift / Combine 中依次执行两个 Promise

问题描述

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

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)))
            }
        }
    }

标签: swiftpromisefunctional-programmingcombine

解决方案


在 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")
}

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

例如:

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")
}

推荐阅读