当用closure/resolver初始化一个promise时,我们可以直接抛出吗?
When initializing a promise with a closure/resolver, can we throw directly?
PromiseKit 具有 Promise
:
的初始值设定项
/// Initialize a new promise that can be resolved with the provided `Resolver`.
public init(resolver body: (PromiseKit.Resolver<T>) throws -> Void)
有时我需要我的函数 return a Promise
但该函数的 return 值取决于其他抛出函数。自 resolver
闭包抛出后,在没有 do/catch
块的情况下直接调用 try
是否有效?或者我必须将每个抛出函数包装在 do
和 catch
调用中 seal.reject(error)
?
我更愿意直接使用 try
,因为它比 return 没有 do/catch
的最终结果更清晰。
这个问题似乎很相关,但我想对这些方法进行一些确认,因为文档中没有提到它:https://github.com/mxcl/PromiseKit/issues/799.
这有效吗?
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
throw CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
}
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
}
}
或者我必须像这样使用 do/catch
:
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
seal.reject(CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]"))
return
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
} catch {
seal.reject(error)
}
}
}
也有这种可能性,但我认为它可能对线程有影响:
private func getCNContacts() -> Promise<[CNContact]> {
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
let error = CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
return Promise(error: error)
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
return Promise.value(results)
} catch {
return Promise(error: error)
}
}
在 Promise 中有抛出函数并且不在 promise 解析块中处理错误是完全有效的。
但是,如果您想处理错误,您可以使用 catch(on: flags:, policy: , _ )
、
这是我根据你的问题做的小实验。
simplePromise = Promise { resolver in
let string = try self.getSomeString()
resolver.resolve(Result.fulfilled(string))
}
simplePromise.done { results in
print(results)
}.catch { error in
print("Error occurred: \(error)")
}
现在,如果我的方法 getSomeString()
抛出异常,则会调用 catch
块内的代码,但如果成功解析,则会调用 done
内的代码。
您可以尝试创建方法 getSomeString
并像这样从那里抛出,
enum MyError: Error {
case sampleError
}
func getSomeString() throws -> String {
throw MyError.sampleError
}
还有,不扔也试试
所以,似乎通常处理抛出函数错误的方法是实现 catch
回调。
您也可以不自己实现 catch 并且您的代码不会崩溃。最后,抛出函数被视为 sealed.reject
顺便说一句,如果你愿意,你可以看看代码。您不必使用 do { } catch
处理错误,但 PromiseKit 会在内部处理,请查看 here 供您参考。
PromiseKit 具有 Promise
:
/// Initialize a new promise that can be resolved with the provided `Resolver`.
public init(resolver body: (PromiseKit.Resolver<T>) throws -> Void)
有时我需要我的函数 return a Promise
但该函数的 return 值取决于其他抛出函数。自 resolver
闭包抛出后,在没有 do/catch
块的情况下直接调用 try
是否有效?或者我必须将每个抛出函数包装在 do
和 catch
调用中 seal.reject(error)
?
我更愿意直接使用 try
,因为它比 return 没有 do/catch
的最终结果更清晰。
这个问题似乎很相关,但我想对这些方法进行一些确认,因为文档中没有提到它:https://github.com/mxcl/PromiseKit/issues/799.
这有效吗?
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
throw CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
}
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
}
}
或者我必须像这样使用 do/catch
:
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
seal.reject(CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]"))
return
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
} catch {
seal.reject(error)
}
}
}
也有这种可能性,但我认为它可能对线程有影响:
private func getCNContacts() -> Promise<[CNContact]> {
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
let error = CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
return Promise(error: error)
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
return Promise.value(results)
} catch {
return Promise(error: error)
}
}
在 Promise 中有抛出函数并且不在 promise 解析块中处理错误是完全有效的。
但是,如果您想处理错误,您可以使用 catch(on: flags:, policy: , _ )
、
这是我根据你的问题做的小实验。
simplePromise = Promise { resolver in
let string = try self.getSomeString()
resolver.resolve(Result.fulfilled(string))
}
simplePromise.done { results in
print(results)
}.catch { error in
print("Error occurred: \(error)")
}
现在,如果我的方法 getSomeString()
抛出异常,则会调用 catch
块内的代码,但如果成功解析,则会调用 done
内的代码。
您可以尝试创建方法 getSomeString
并像这样从那里抛出,
enum MyError: Error {
case sampleError
}
func getSomeString() throws -> String {
throw MyError.sampleError
}
还有,不扔也试试
所以,似乎通常处理抛出函数错误的方法是实现 catch
回调。
您也可以不自己实现 catch 并且您的代码不会崩溃。最后,抛出函数被视为 sealed.reject
顺便说一句,如果你愿意,你可以看看代码。您不必使用 do { } catch
处理错误,但 PromiseKit 会在内部处理,请查看 here 供您参考。