如何执行接连完成的多个Alamofire请求? [英] How is it possible to perform multiple Alamofire requests that are finished one after another?
问题描述
我想执行多个Alamofire请求。但是,由于数据依赖性,新请求仅应在前一个请求完成时才开始。
I would like to perform multiple Alamofire requests. However, because of data dependency a new request should only start when the previous is finished.
我已经问过,其中有一个更一般的异步请求示例,该示例由 OperationQueue
解决。但是,我无法通过Alamofire实现相同的功能。
I already asked a question with a more general example of an asynchronous request which was solved with OperationQueue
. However, I do not succeed to achieve the same with Alamofire.
public func performAlamofireRequest(_ number: Int, success: @escaping (Int) -> Void)->Void {
Alamofire.request(String(format: "http://jsonplaceholder.typicode.com/posts/%i", number+1)) // NSURLSession dispatch queue
.responseString { response in // Completion handler at main dispatch queue?
if response.result.isSuccess {
// print("data")
} else if response.result.isFailure {
// print("error")
}
success(number) // Always leave closure in this example
}
}
为了确保在下一个请求开始之前完成请求,我使用 OperationQueue
如下:
To assure that requests are finished before a next request is started, I use OperationQueue
as follows:
let operationQueue = OperationQueue.main
for operationNumber in 0..<4 { // Create some operations
let operation = BlockOperation(block: {
performAlamofireRequest(operationNumber) { number in
print("Operation #\(number) finished")
}
})
operation.name = "Operation #\(operationNumber)"
if operationNumber > 0 {
operation.addDependency(operationQueue.operations.last!)
}
operationQueue.addOperation(operation)
}
但是,输出为:
Operation #0 finished
Operation #3 finished
Operation #2 finished
Operation #1 finished
这显然是不正确的。
如何用Alamofire做到这一点?
How would it be possible to achieve this with Alamofire?
推荐答案
问题与您提出的相关问题:如文档所述,操作依赖项是对操作的完成,但是您已经编写了代码,其中该操作在异步调度将来执行的请求后退出操作(您创建并添加到的操作队列将按照其依赖关系设置的顺序完成,但请求将由Alamofire底层的NSURLSession并发触发。
The issue is just the same as in the related question you posed: the operation dependencies are on finishing an operation, as documented, but you have written code where the operation exits after asynchronously dispatching a request for future execution (the operations you created and added to a queue will finish in the order set by their dependencies, but the requests will be fired concurrently by the NSURLSession underlying Alamofire).
如果需要串行执行,则可以执行以下操作:
If you need serial execution, you can for instance do the following:
// you should create an operation queue, not use OperationQueue.main here –
// synchronous network IO that would end up waiting on main queue is a real bad idea.
let operationQueue = OperationQueue()
let timeout:TimeInterval = 30.0
for operationNumber in 0..<4 {
let operation = BlockOperation {
let s = DispatchSemaphore(value: 0)
self.performAlamofireRequest(operationNumber) { number in
// do stuff with the response.
s.signal()
}
// the timeout here is really an extra safety measure – the request itself should time out and end up firing the completion handler.
s.wait(timeout: DispatchTime(DispatchTime.now, Int64(timeout * Double(NSEC_PER_SEC))))
}
operationQueue.addOperation(operation)
}
讨论了各种其他解决方案 ,可以说是重复的。还有 Alamofire-Synchronous 。
Various other solutions are discussed in connection to this question, arguably a duplicate. There's also Alamofire-Synchronous.
这篇关于如何执行接连完成的多个Alamofire请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!