[英]Alamofire synchronous request with a loop
I know how to make a synchronous request with completions. 我知道如何与完成请求同步。 But I don't know how to make synchronous requests in a loop. 但是我不知道如何在循环中发出同步请求。
Here is my code: 这是我的代码:
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)
}
}
}
}
Here I'm trying to make x requests with the number of vn codes ( vnCount
). 在这里,我尝试使用vn代码( vnCount
)的数量发出x个请求。 The issue is that I get all the JSON in a wrong order in my array of JSON marks
. 问题是我在JSON marks
数组中以错误的顺序获取了所有JSON。 Certainly because it appends responses in the array when it's finished and don't wait the previous request to be ended. 当然是因为它在完成时将响应添加到数组中,而不必等待先前的请求结束。
So I tried to create a variable i
to force the function to append responses in the right order. 因此,我尝试创建一个变量i
来强制该函数以正确的顺序附加响应。 That's not working. 那不行 Any idea? 任何想法? Thanks! 谢谢!
You can run your requests sequentially in a serial queue, in which case they will be executed in the order you call them, which ensures they will be added to the array in order. 您可以在串行队列中顺序运行请求,在这种情况下,它们将按照调用它们的顺序执行,以确保将它们按顺序添加到数组中。 However, this seems like a suboptimal solution, since you lose execution time by running your requests sequentially instead of concurrently. 但是,这似乎是次优的解决方案,因为您通过顺序而不是同时运行请求来浪费执行时间。
If you still want to implement it like this, see the code below: 如果仍要像这样实现它,请参见下面的代码:
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)
}
}
}
}
}
A better solution would be to store the response in a data structure, where ordering doesn't matter, for example in a dictionary, where your keys are the indexes (which you would use for an array) and your values are the JSON response values. 更好的解决方案是将响应存储在数据结构中,其中顺序无关紧要,例如在字典中,其中键是索引(将用于数组),值是JSON响应值。 This way you can run the requests concurrently and access the responses in order. 这样,您可以同时运行请求并按顺序访问响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.