【发布时间】:2020-11-29 08:49:28
【问题描述】:
我正在使用Amadeus API 进行航班搜索。 Amadeus API 要求请求的频率不得超过 1/100 毫秒。我使用下面的代码来限制请求频率
for depDate in depDates{
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
AmadeusHelper.sharedInstance().searchAFlight(depAirport: depAirport, arrAirport: arrAirport, depDate: depDate, airlineCode: airlineCode, flightNumber: flightNum) { result in
switch result{
case .failure(let err):
print(err)
case .success(let flightOffer):
if let json = flightOffer.get(){
flightCandidate.offers?.append(json)
}
}
}
}
}
上面的for-loop 运行了 4 个循环。 searchAFlight 函数本质上是HTTP request 的包装。 asyncAfter 函数会将每个请求延迟 1 秒。我以为这就够了。但是,我仍然收到tooManyRequests 错误。在调试的时候,我是按照代码一步一步来的,发送请求需要更长的时间。请求应该分散在几分钟内,足够长以满足 100 毫秒的间隔。我在这里做错了吗?谢谢。
===========更新=========
根据Eric的cmets,我把代码改成如下
var timeNow = DispatchTime.now() // each request is delayed with an increasing interval
for (index, depDate) in depDates.enumerated(){
DispatchQueue.main.asyncAfter(deadline: timeNow + Double(1*index)) {
AmadeusHelper.sharedInstance().searchAFlight(depAirport: depAirport, arrAirport: arrAirport, depDate: depDate, airlineCode: airlineCode, flightNumber: flightNum) { result in
switch result{
case .failure(let err):
print(err)
case .success(let flightOffer):
if let json = flightOffer.get(){
flightCandidate.offers?.append(json)
}
}
}
}
}
不幸的是,我仍然收到tooManyRequest 错误。
【问题讨论】:
-
DispatchQueue.main.asyncAfter(deadline: .now() + 1)所做的只是抵消请求将 开始 的时刻,但它们仍然会按顺序执行得非常快(因为循环),一旦第一个一个已经开始(它们都在同一时间偏移)。 -
谢谢@EricAya 你有什么建议可以按照要求的间隔执行四个请求吗?计时器?
-
嗨@EricAya 我尝试了单个请求(不使用
semaphore,但只发送一个请求),它工作正常。我会尝试semaphore和timer。但这里有一件事是,API 有时不会调用完成处理程序。您给出的示例在完成处理程序中有一个semaphore.signal()。有什么建议在这里添加一些超时逻辑吗?谢谢!
标签: swift httprequest amadeus