如何处理 Swifty JSON Alamofire 请求中的优先级?
How to handle priorities in a Swifty JSON Alamofire request?
我如何使用 Javascript 中的 dispatchQueue 或类似 "await" 的东西来 return self.arrayData
中的值(因为我的循环结束是 运行 在前面的内容之前)。我习惯了代码逐行运行的 R 和 Python,在 Swift 中采用的最佳行为是什么?
函数如下:
func fetch2(){
var i:Int = 0
repeat {
AF.request(itemLookUp[i]).validate().responseJSON { response in
switch response.result {
case .failure(let error):
print("\(error) in fetch2")
case .success(let value):
let json = JSON(value)
//Extract the Matiere for ML Extraction
self.matiereInput = json["ResultSet"]["0"]["Result"]["0"]["SpAdditional"].string ?? "none"
let energyCheck:Bool = self.matiereInput.contains("エネルギー") //energy-kcal
if energyCheck==true && self.arrayData[0]==0.0{
//regular expression
var patEnergy = #"(エネルギー)(([^\d]+)(\d+)(\.)(\d+)|([^\d]+)(\d+))"# //avoid the repetition of the pattern within the same matiereinput
let patEnergy2 = self.matches(for: patEnergy, in: self.matiereInput)
patEnergy = patEnergy2.joined(separator:"")
let valueEnergy = self.matches(for: self.regex2, in: patEnergy)
self.arrayData[0] = Double(valueEnergy.joined(separator: "")) ?? 0.0
}
}
}
i = i+1
print(self.arrayData[0])
} while i <= (self.returned-1)
}
提前致谢!
标准模式是 notify
和 DispatchGroup
,然后使用完成处理程序异步通知调用者结果:
func fetchAll(completion: @escaping (Result<[Double], Error>) -> Void) {
let group = DispatchGroup()
var results: [Double] = []
var errors: [Error] = []
for item in lookupItems {
group.enter() // enter before request
AF.request(item).validate().responseJSON { response in
defer { group.leave() } // leave when this closure is done
switch response.result {
case .failure(let error):
errors.append(error)
case .success(let value):
let result = ...
results.append(result)
}
}
}
group.notify(queue: .main) {
if let error = errors.first { // I don’t know what you want to do if there were multiple errors, so for now I’ll just grab the first one
completion(.failure(error))
} else {
completion(.success(results))
}
}
}
然后你会像这样使用它:
fetchAll { result in
switch result {
case .failure(let error):
print(error)
case .success(let values):
print(values)
}
}
现在,我无法对你试图做的事情进行逆向工程(你似乎在每次迭代中都在更新 self.arrayData[0]
!),所以我只返回了一个 Double
的数组.但是您显然可以更改 results
的类型和 completion
闭包的参数以匹配与您的情况相关的任何内容。
但不要迷失在上面示例的细节中,而是只关注几个关键观察结果:
- 提供完成处理程序闭包以在所有请求完成时调用。
- 使用
DispatchGroup
跟踪所有请求何时完成。
- 为您的
DispatchGroup
提供一个 notify
闭包,当所有 group.enter()
调用被它们各自的 group.leave()
调用抵消时将被调用。
- 一个更微妙的观察是您应该避免从
responseJSON
块中更新属性。在您的异步代码中,如果可能的话,您真的希望将您的交互限制在局部变量中。将结果传回 completion
闭包(并且调用者可以根据需要更新模型和 UI )。
我如何使用 Javascript 中的 dispatchQueue 或类似 "await" 的东西来 return self.arrayData
中的值(因为我的循环结束是 运行 在前面的内容之前)。我习惯了代码逐行运行的 R 和 Python,在 Swift 中采用的最佳行为是什么?
函数如下:
func fetch2(){
var i:Int = 0
repeat {
AF.request(itemLookUp[i]).validate().responseJSON { response in
switch response.result {
case .failure(let error):
print("\(error) in fetch2")
case .success(let value):
let json = JSON(value)
//Extract the Matiere for ML Extraction
self.matiereInput = json["ResultSet"]["0"]["Result"]["0"]["SpAdditional"].string ?? "none"
let energyCheck:Bool = self.matiereInput.contains("エネルギー") //energy-kcal
if energyCheck==true && self.arrayData[0]==0.0{
//regular expression
var patEnergy = #"(エネルギー)(([^\d]+)(\d+)(\.)(\d+)|([^\d]+)(\d+))"# //avoid the repetition of the pattern within the same matiereinput
let patEnergy2 = self.matches(for: patEnergy, in: self.matiereInput)
patEnergy = patEnergy2.joined(separator:"")
let valueEnergy = self.matches(for: self.regex2, in: patEnergy)
self.arrayData[0] = Double(valueEnergy.joined(separator: "")) ?? 0.0
}
}
}
i = i+1
print(self.arrayData[0])
} while i <= (self.returned-1)
}
提前致谢!
标准模式是 notify
和 DispatchGroup
,然后使用完成处理程序异步通知调用者结果:
func fetchAll(completion: @escaping (Result<[Double], Error>) -> Void) {
let group = DispatchGroup()
var results: [Double] = []
var errors: [Error] = []
for item in lookupItems {
group.enter() // enter before request
AF.request(item).validate().responseJSON { response in
defer { group.leave() } // leave when this closure is done
switch response.result {
case .failure(let error):
errors.append(error)
case .success(let value):
let result = ...
results.append(result)
}
}
}
group.notify(queue: .main) {
if let error = errors.first { // I don’t know what you want to do if there were multiple errors, so for now I’ll just grab the first one
completion(.failure(error))
} else {
completion(.success(results))
}
}
}
然后你会像这样使用它:
fetchAll { result in
switch result {
case .failure(let error):
print(error)
case .success(let values):
print(values)
}
}
现在,我无法对你试图做的事情进行逆向工程(你似乎在每次迭代中都在更新 self.arrayData[0]
!),所以我只返回了一个 Double
的数组.但是您显然可以更改 results
的类型和 completion
闭包的参数以匹配与您的情况相关的任何内容。
但不要迷失在上面示例的细节中,而是只关注几个关键观察结果:
- 提供完成处理程序闭包以在所有请求完成时调用。
- 使用
DispatchGroup
跟踪所有请求何时完成。 - 为您的
DispatchGroup
提供一个notify
闭包,当所有group.enter()
调用被它们各自的group.leave()
调用抵消时将被调用。 - 一个更微妙的观察是您应该避免从
responseJSON
块中更新属性。在您的异步代码中,如果可能的话,您真的希望将您的交互限制在局部变量中。将结果传回completion
闭包(并且调用者可以根据需要更新模型和 UI )。