从 PromiseKit/Alamofire 返回一个 Promise
Returning a Promise from PromiseKit/Alamofire
我正在尝试做这件看似微不足道的事情:
static func list() -> Promise<[Activity]> {
let endpoint = "\(self.baseUrl)/v1/activities"
return Promise { fulfill, reject in
self.fetchHeaders { (headers) in
return Alamofire.request(
endpoint,
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: headers
).validate().responseJSON().then() { response in
guard let json = response as? JSON else {
reject(ActivityError.parse("Malformed JSON"))
}
guard let jsonActivities = json["activities"] as? [JSON] else {
reject(ActivityError.parse("Missing field"))
}
var activities: [Activity] = []
for jsonActivity in jsonActivities {
guard let activity = Activity(json: jsonActivity) else {
reject(ActivityError.parse("Unable to parse an Activity object"))
}
activities.append(activity)
}
fulfill(activities)
}.catch { error in
reject(ActivityError.network("HTTP response failure"))
}
}
}
}
但是,编译器(理所当然地)抱怨说:
'guard' body may not fall through, consider using 'return' or 'break'
to exit the scope
我明白我需要 return 一个承诺。我只是不知道在 reject() 和 fulfill() 调用下面到底放了什么。
reject
或 fulfill
调用没有任何问题。问题是,在 guard
语句中 reject
之后,您还必须 return
退出闭包:
guard let json = response as? JSON else {
reject(ActivityError.parse("Malformed JSON"))
return
}
guard let jsonActivities = json["activities"] as? [JSON] else {
reject(ActivityError.parse("Missing field"))
return
}
关键是您不想将通过此方法 returned 的承诺(稍后由 fulfill
或 reject
满足)与事实上,在这个闭包中,你必须立即在 guard
子句中使用 return
退出闭包。
我无法用你的代码重现这个问题(因为你没有提供 MCVE 并且这里有我无法解决的参考)。但这里是您的代码的简化版本,说明了 guard
:
的用法
所以,如果不使用 PromiseKit/Alamofire,你可以这样做:
func list() -> Promise<[String: Any]> {
return Promise { fulfill, reject in
Alamofire.request(url)
.validate()
.responseJSON { response in
switch response.result {
case .success(let json):
guard let dictionary = json as? [String: Any] else {
reject(ActivityError.malformed("not a dictionary"))
return
}
fulfill(dictionary)
case .failure(let error):
reject(error)
}
}
}
}
如您所见,您正在 return 执行 Promise
,但在 Alamofire 闭包内,您只是退出 guard
语句。
如果您正在使用 PromiseKit/Alamofire 并调用 then
,您可能想要创建一个它可以 return 的承诺,例如:
func list() -> Promise<String> {
return Alamofire.request(endPoint)
.validate()
.responseJSON()
.then { value in
return Promise { fulfill, reject in
guard let dictionary = value as? [String: Any], let name = dictionary["name"] as? String else {
reject(ActivityError.malformed("not dictionary"))
return
}
fulfill(name)
}
}
}
或者如果这太麻烦了,您可以提取 value
:
的解析
func list() -> Promise<String> {
return Alamofire.request(endPoint)
.validate()
.responseJSON()
.then { value in
self.parse(value)
}
}
func parse(_ value: Any) -> Promise<String> {
return Promise { fulfill, reject in
guard let dictionary = value as? [String: Any], let name = dictionary["name"] as? String else {
reject(ActivityError.malformed("not dictionary"))
return
}
fulfill(name)
}
}
但是,无论哪种方式,即使使用 PromiseKit/Alamofire,您仍然只是 guard
子句中的 return
。
我正在尝试做这件看似微不足道的事情:
static func list() -> Promise<[Activity]> {
let endpoint = "\(self.baseUrl)/v1/activities"
return Promise { fulfill, reject in
self.fetchHeaders { (headers) in
return Alamofire.request(
endpoint,
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: headers
).validate().responseJSON().then() { response in
guard let json = response as? JSON else {
reject(ActivityError.parse("Malformed JSON"))
}
guard let jsonActivities = json["activities"] as? [JSON] else {
reject(ActivityError.parse("Missing field"))
}
var activities: [Activity] = []
for jsonActivity in jsonActivities {
guard let activity = Activity(json: jsonActivity) else {
reject(ActivityError.parse("Unable to parse an Activity object"))
}
activities.append(activity)
}
fulfill(activities)
}.catch { error in
reject(ActivityError.network("HTTP response failure"))
}
}
}
}
但是,编译器(理所当然地)抱怨说:
'guard' body may not fall through, consider using 'return' or 'break' to exit the scope
我明白我需要 return 一个承诺。我只是不知道在 reject() 和 fulfill() 调用下面到底放了什么。
reject
或 fulfill
调用没有任何问题。问题是,在 guard
语句中 reject
之后,您还必须 return
退出闭包:
guard let json = response as? JSON else {
reject(ActivityError.parse("Malformed JSON"))
return
}
guard let jsonActivities = json["activities"] as? [JSON] else {
reject(ActivityError.parse("Missing field"))
return
}
关键是您不想将通过此方法 returned 的承诺(稍后由 fulfill
或 reject
满足)与事实上,在这个闭包中,你必须立即在 guard
子句中使用 return
退出闭包。
我无法用你的代码重现这个问题(因为你没有提供 MCVE 并且这里有我无法解决的参考)。但这里是您的代码的简化版本,说明了 guard
:
所以,如果不使用 PromiseKit/Alamofire,你可以这样做:
func list() -> Promise<[String: Any]> {
return Promise { fulfill, reject in
Alamofire.request(url)
.validate()
.responseJSON { response in
switch response.result {
case .success(let json):
guard let dictionary = json as? [String: Any] else {
reject(ActivityError.malformed("not a dictionary"))
return
}
fulfill(dictionary)
case .failure(let error):
reject(error)
}
}
}
}
如您所见,您正在 return 执行 Promise
,但在 Alamofire 闭包内,您只是退出 guard
语句。
如果您正在使用 PromiseKit/Alamofire 并调用 then
,您可能想要创建一个它可以 return 的承诺,例如:
func list() -> Promise<String> {
return Alamofire.request(endPoint)
.validate()
.responseJSON()
.then { value in
return Promise { fulfill, reject in
guard let dictionary = value as? [String: Any], let name = dictionary["name"] as? String else {
reject(ActivityError.malformed("not dictionary"))
return
}
fulfill(name)
}
}
}
或者如果这太麻烦了,您可以提取 value
:
func list() -> Promise<String> {
return Alamofire.request(endPoint)
.validate()
.responseJSON()
.then { value in
self.parse(value)
}
}
func parse(_ value: Any) -> Promise<String> {
return Promise { fulfill, reject in
guard let dictionary = value as? [String: Any], let name = dictionary["name"] as? String else {
reject(ActivityError.malformed("not dictionary"))
return
}
fulfill(name)
}
}
但是,无论哪种方式,即使使用 PromiseKit/Alamofire,您仍然只是 guard
子句中的 return
。