在 then 块中拒绝返回的承诺

Posted

技术标签:

【中文标题】在 then 块中拒绝返回的承诺【英文标题】:Rejecting a the returned promise inside a then block 【发布时间】:2017-03-30 17:57:01 【问题描述】:

假设我有两个要与when(resolved:) 结合的承诺。如果第一个承诺有问题,我想拒绝该承诺,否则解决。本质上,这就是我想要做的:

func personAndPetPromise() -> Promise<(Person, Pet?)> 
    let personPromise: Promise<Person> = ...
    let petPromise: Promise<Pet> = ...

    when(resolved: personPromise, petPromise).then  _ -> (Person, Pet?) in
        if let error = personPromise.error 
            return Promise(error: error) // syntax error
        
        guard let person = personPromise.value else 
            return Promise(error: myError) // syntax error
        
        return (person, petPromise.value)
    

这样我就可以在外部做这样的事情:

personAndPetPromise().then  person, pet in
    doSomethingWith(person, pet)
.catch  error in
    showError(error)

问题出在personAndPetPromise 中的then _ in 块内。该方法不可能同时返回 Promise(error:)(Person, Pet?)

我还能如何拒绝阻止?

【问题讨论】:

【参考方案1】:

问题是then函数有两个重载:

public func then<U>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> U) -> Promise<U>
public func then<U>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> Promise<U>) -> Promise<U>

第一个body 返回U 并导致then 返回Promise&lt;U&gt;

第二个body 返回Promise&lt;U&gt; 并导致then 返回Promise&lt;U&gt;

由于在这种情况下我们想要返回错误或有效响应,因此我们不得不使用第二个重载。

这是一个工作版本。主要区别是我将它从-&gt; (Person, Pet?) 更改为-&gt; Promise&lt;(Person, Pet?)&gt;

func personAndPetPromise() -> Promise<(Person, Pet?)> 
    let personPromise: Promise<Person> = ...
    let petPromise: Promise<Pet> = ...

    when(resolved: personPromise, petPromise).then  _ -> Promise<(Person, Pet?)> in
        if let error = personPromise.error 
            return Promise(error: error)
        
        guard let person = personPromise.value else 
            return Promise(error: myError)
        
        return Promise(value: (person, petPromise.value))
    

做同样事情的另一种方法是抛出错误,而不是试图返回它:

func personAndPetPromise() -> Promise<(Person, Pet?)> 
    let personPromise: Promise<Person> = ...
    let petPromise: Promise<Pet> = ...

    when(resolved: personPromise, petPromise).then  _ -> (Person, Pet?) in
        if let error = personPromise.error 
            throw error
        
        guard let person = personPromise.value else 
            throw myError
        
        return (person, petPromise.value)
    

【讨论】:

以上是关于在 then 块中拒绝返回的承诺的主要内容,如果未能解决你的问题,请参考以下文章

承诺按顺序运行嵌套承诺并在第一次拒绝时解决

我如何测试返回承诺或拒绝的函数 - Jasmine 和 Karma

返回承诺的 Vuex 操作永远不会解析或拒绝

从 vuex 存储操作中的承诺返回错误

Node.JS - 无法使用try / catch块获得异步抛出

如何保证承诺不会拒绝的API用户