我有一个iOS应用程序,它使用Alamofire发出URL请求。当它们之间的时间很短时,我有时会发现请求以错误的顺序到达。这与我理解的异步请求的性质有关。有没有办法保证请求的正确顺序?我一直在想你可以等待每个请求完成,因为你有一个完成处理程序,或者你可以在服务器端处理这个,每个请求都有一个时间戳,这样服务器就可以丢弃时间戳较低的请求。我不知道什么是最好的解决方案。
到目前为止我的代码:
Alamofire.request(
defaults.string(forKey: "APIurl")! + path,
method: httpMethod,
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers).responseJSON
{ response in
// Check if the request was successful
var success = false
if (response.result.isSuccess) {
let statusCode = response.response!.statusCode
if (statusCode == 200) {
success = true
} else {
showAlert("COULD_NOT_COMPLETE_TASK_TITLE", message: "TRY_AGAIN_LATER")
}
}
}
我使用滑块来更改介于0和100之间的值。因此,在我的情况下,请求的顺序至关重要。假设我将滑块从50更改为60.对于异步请求,它有时会先执行60然后执行50.这是一个问题,因为它以这种方式发送到我的API并将最新值(在本例中为50)保存在数据库中虽然我想要的值是60。
答案 0 :(得分:0)
如果线程是串行的,那么在你的情况下,它的顺序将始终与你输入的相同。因此,在同一个串行线程上异步调用一些操作将强制操作保留该顺序。
你的案子中的问题是你没有打电话给这些行动,Alamofire正在打电话给他们。保留顺序,但这取决于接收和解析响应的时间。这意味着您可能无法控制被调用的异步操作的顺序。
您有2种序列化响应的方法:
在调用下一个请求之前,您需要等待每个响应完成。如果您的回答是标准的(所有看起来都很相似),您只需要一些管理器来存储一系列请求,并且在前一个请求完成之前不会调用新请求。这可能有点慢,因为没有理由(或者至少在你的情况下看起来那样)不能同时执行请求。
序列化响应,以便按照与输入相同的顺序调用它们。这意味着您可以随时调用请求,并随时调用响应。但是一旦收到回复,您将检查其他响应是否完整,只有在它们出现时才会触发回复。这也意味着让一些经理将序列化回复。
所以对于第二个你需要的东西:
SerializedRequestManager.performRequest(request, myCallbackClosure)
然后,管理器会将请求保存到一些请求包装器数组中,如:
let requestWrapper = RequestWrapper(request, myCallbackClosure, isCompleted: false)
self.requestPool.append(requestWrapper)
AF.performRequest(request, myInternalClosure)
然后在响应(myInternalClosure
)上,您需要设置正确的包装器以响应true,然后从数组的开头刷新响应。然后必须从数组中删除所有完成的响应:
requestWrapper.responseData = data // Same wrapper that was just added into the array
requestWrapper.responseError = error // Same wrapper that was just added into the array
requestWrapper.isCompleted = true
self.flushResponses()
然后是flushResponses
:
var newPool = [RequestWrapper]() // This is where all the pending items will stay
var shouldFlushResponse = true // Will be set to false with first request that was not completed
self.requestPool.forEach { wrapper in
if wrapper.isCompleted && shouldFlushResponse {
wrapper.callback(wrapper.responseData, wrapper.responseError) // perform response closure
} else {
shouldFlushResponse = false
newPool.append(wrapper)
}
}
self.requestPool = newPool
但是你需要在这里对多线程非常小心。数组requestPool
上的所有操作都应该在同一个线程上完成,但它可能是你想要的任何线程。
答案 1 :(得分:0)
如果您的案件中的请求顺序很重要,那么您应该去NSOperationQueue,这是确保您的请求顺序的唯一方法。
关注this教程以获得边框构思