gpt4 book ai didi

ios - 如何保证异步请求的正确顺序

转载 作者:行者123 更新时间:2023-11-30 12:22:18 25 4
gpt4 key购买 nike

我有一个使用 Alamofire 发出 URL 请求的 iOS 应用程序。有时我会发现请求到达的顺序是错误的,而它们之间的时间间隔很短。据我了解,这与异步请求的性质有关。有什么办法可以保证请求的顺序正确吗?我一直在想您可以等待每个请求完成,因为您有一个完成处理程序,或者您可以在服务器端处理每个请求的时间戳,以便服务器可以丢弃具有较低时间戳的请求。但我不知道最好的解决方案是什么。

到目前为止我的代码:

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")
}
}

}

我使用 slider 更改 0 到 100 之间的值。因此,就我而言,请求的顺序至关重要。假设我将 slider 从 50 更改为 60。对于异步请求,它有时会先执行 60,然后执行 50。这是一个问题,因为它会以这种方式发送到我的 API,甚至会在数据库中保存最新值(在本例中为 50)虽然我想要的值为 60。

最佳答案

如果线程是串行的(在您的情况下是串行的),那么顺序将始终与您输入的顺序相同。因此,在同一串行线程上异步调用一些操作将强制这些操作保留该顺序。

您的情况的问题是您没有调用这些操作,Alamofire 正在调用它们。顺序会被保留,但取决于响应的接收和解析时间。这意味着您可能无法控制调用异步操作的顺序。

您有两种序列化响应的方法:

  1. 您需要等待每个响应完成后才能调用下一个请求。如果您的响应是标准的(看起来都很相似),您只需要一些管理器来存储一组请求,并且在前一个请求完成之前不会调用新的请求。这可能会有点慢,因为没有理由(或者至少在您的情况下看起来是这样)不同时执行请求。

  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 的所有操作都应该在同一线程上完成,但也可以是您想要的任何线程。

关于ios - 如何保证异步请求的正确顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44646733/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com