PromiseKit 6.0 将捕捉到的错误传递给调用者
PromiseKit 6.0 passing catched errors to caller
根据迁移指南 PromiseKit 6.x 更改了他关于 catch
块的策略。在 PMK 4 中,catch
返回了它所附加的承诺。现在 catch
是链终止符。我明白为什么要进行这些更改,但是...
在我的代码库(与 PK4 相关)中,我从 catch
returns 承诺中获得了一些好处。
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 中,我想显示例如错误或成功对话框。
这就是一个 Promise 链需要两个 catch
es 的原因。一份用于 authorizationService
,一份用于 UI
。
PromiseKit6 中是否有任何变通方法可以实现此目的?
编辑
我找到了两个解决方案(解决方法)。我创建了两个答案来将它们分开。未来的读者可以决定哪一个更好或提供新的。
我已将我的 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([=10=])
_ = self.authorizationService.markAsServerUnsynced()
seal.reject([=10=])
}
}
}
应该可行,但我不知道这是不是一个好方法。
我发现 (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()
}
}
对于文档:
tap
feeds you the current Result for the chain, so is called if the chain is succeeding or if it is failing
所以我可以为终止链的 Promise 当前状态提供自定义错误处理。 Promise 可以发送给发件人,在那里我可以做另一个 tap
或通过 catch
.
终止链
根据迁移指南 PromiseKit 6.x 更改了他关于 catch
块的策略。在 PMK 4 中,catch
返回了它所附加的承诺。现在 catch
是链终止符。我明白为什么要进行这些更改,但是...
在我的代码库(与 PK4 相关)中,我从 catch
returns 承诺中获得了一些好处。
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 中,我想显示例如错误或成功对话框。
这就是一个 Promise 链需要两个 catch
es 的原因。一份用于 authorizationService
,一份用于 UI
。
PromiseKit6 中是否有任何变通方法可以实现此目的?
编辑
我找到了两个解决方案(解决方法)。我创建了两个答案来将它们分开。未来的读者可以决定哪一个更好或提供新的。
我已将我的 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([=10=])
_ = self.authorizationService.markAsServerUnsynced()
seal.reject([=10=])
}
}
}
应该可行,但我不知道这是不是一个好方法。
我发现 (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()
}
}
对于文档:
tap
feeds you the current Result for the chain, so is called if the chain is succeeding or if it is failing
所以我可以为终止链的 Promise 当前状态提供自定义错误处理。 Promise 可以发送给发件人,在那里我可以做另一个 tap
或通过 catch
.