根据迁移指南,PromiseKit 6.x改变了他关于catch
块的政策。在PMK 4 catch
返回了附加的承诺。现在catch
是一个链终结者。我明白为什么要做出这些改变但是......
在我的代码库中(与PK4连接)我从catch
返回promise中获得了一些优势。
func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
synchronizationService.stopAllRunningSingleSynchronizations()
return
authorizationService.save(serverAddress: address, andPort: port)
.then {
self.synchronizationService.startSingleFullSynchronization()
}
.then {
self.authorizationService.markAsServerSynced()
}
.catch { error in
log.error(error)
_ = self.authorizationService.markAsServerUnsynced()
}
}
在这个函数中,我做了一些逻辑,在某些情况下可以使用。如果出现错误catch
阻塞应该做出一些逻辑,但我还想向loginAndSync
函数调用者发送此承诺的结果(履行或拒绝)。上面的函数可以通过ViewController调用,在ViewController中我想显示例如Error或Success Dialog。
这是我需要两个catch
es用于一个Promise链的原因。一个用于authorizationService
,另一个用于UI
。
PromiseKit6中是否有解决方法来实现这一目标?
我找到了两个解决方案(解决方法)。我创建了两个将它们分开的答案。未来的读者可以决定哪一个更好或者提供新的。
答案 0 :(得分:2)
我发现(IMO)更好的解决方法。 PromiseKit6引入了非常方便的方法tap
。我试过用它来解决我的问题。
func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
synchronizationService.stopAllRunningSingleSynchronizations()
return authorizationService.save(serverAddress: address, andPort: port)
.then {
self.synchronizationService.startSingleFullSynchronization()
}
.then {
self.authorizationService.markAsServerSynced()
}
.tap { result in
switch result {
case .rejected(let error):
log.error(error)
_ = self.authorizationService.markAsServerUnsynced()
default: break
}
}
.done {
self.coordinatorDelegate?.handleLoginServerSuccess()
}
}
对于doc:
tap
为您提供链的当前结果,因此如果链成功或者失败则调用
因此,我可以为终止链的Promise whit的当前状态提供自定义错误处理。承诺可以发送给发件人,我可以通过tap
发送另一个catch
或终止链。
答案 1 :(得分:0)
我把我的Promise链包装在另一个Promise中:
func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
synchronizationService.stopAllRunningSingleSynchronizations()
return Promise { seal in
authorizationService.save(serverAddress: address, andPort: port)
.then {
self.synchronizationService.startSingleFullSynchronization()
}
.then {
self.authorizationService.markAsServerSynced()
}
.done {
self.coordinatorDelegate?.handleLoginServerSuccess()
seal.fulfill(())
}
.catch {
log.error($0)
_ = self.authorizationService.markAsServerUnsynced()
seal.reject($0)
}
}
}
它应该有效,但我不知道这是一个好方法。