我知道如何使用完成进行同步请求。但我不知道如何在循环中发出同步请求。
这是我的代码:
var marks = [JSON]()
let vnCount = studentVnCodes.count
var i: Int = 0
marks = [JSON](repeating: JSON.null, count: vnCount)
for vn in studentVnCodes {
let url = "https://example.com/Student/Grade/GetFinalGrades?&vn=\(vn)&academic_year=All"
Alamofire.request(url).responseString { response in
var dataString: String = (response.result.value)!
dataString = cleanMarksJSON(string: dataString)
if let dict = convertToDictionary(text: dataString) {
marks[i] = (JSON(dict as Any))
i += 1
if (vnCount == marks.count) {
completionHandler(marks)
}
}
}
}
我尝试使用vn代码(vnCount
)进行x请求。
问题是我在JSON marks
数组中以错误的顺序获取所有JSON。当然,因为它在数组完成时会在数组中附加响应,并且不会等待先前的请求结束。
所以我尝试创建一个变量i
来强制函数以正确的顺序附加响应。这不起作用。任何的想法?谢谢!
答案 0 :(得分:1)
您可以在串行队列中按顺序运行请求,在这种情况下,它们将按您调用它们的顺序执行,这可确保它们按顺序添加到阵列中。但是,这似乎是一个次优的解决方案,因为您通过顺序而不是同时运行请求来减少执行时间。
如果您仍想像这样实现它,请参阅以下代码:
var marks = [JSON]()
let vnCount = studentVnCodes.count
marks = [JSON](repeating: JSON.null, count: vnCount)
let serialQueue = DispatchQueue(label: "serialQueue")
for vn in studentVnCodes {
serialQueue.async{
let url = "https://example.com/Student/Grade/GetFinalGrades?&vn=\(vn)&academic_year=All"
Alamofire.request(url).responseString { response in
var dataString: String = (response.result.value)!
dataString = cleanMarksJSON(string: dataString)
if let dict = convertToDictionary(text: dataString) {
marks.append(JSON(dict as Any))
if (vnCount == marks.count) {
completionHandler(marks)
}
}
}
}
}
更好的解决方案是将响应存储在数据结构中,其中排序并不重要,例如在字典中,您的键是索引(您将用于数组)和您的值是JSON响应值。这样,您可以同时运行请求并按顺序访问响应。