Отклонение возвращенного обещания внутри блока then
Скажем, у меня есть два обещания, которые я хочу совместить с 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)
}
Проблема заключается в then { _ in
блокировать в personAndPetPromise
, Там нет никакого способа, которым этот метод может вернуть как 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<U>
,
Второй body
возвращает Promise<U>
и причины then
возвращать Promise<U>
,
Поскольку в этом случае мы хотим вернуть ошибку или действительный ответ, мы вынуждены использовать вторую перегрузку.
Вот рабочая версия. Основное отличие в том, что я изменил -> (Person, Pet?)
в -> Promise<(Person, Pet?)>
:
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)
}
}