You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中SwiftRateLimiter处理Directions请求限流问题咨询

Directions请求限流问题及SwiftRateLimiter用法疑问

我遇到了Directions请求限流问题,提示信息:

"Throttled "Directions" request: Tried to make more than 50 requests in 60 seconds"

因此尝试集成SwiftRateLimiter库来控制请求频率。

调用getDistanceBetweenLocations的代码

_ = circleQuery?.observe(.keyEntered, with: {(key: String?, location: CLLocation?) in
            mapCoord[key!] = location?.coordinate //stores busID and it's coord in Dictionary
            self.getBusinessData(bus: key!)
            if (!searchBus.contains(key!)){
                searchBus.append(key!)
                
                self.getDistanceBetweenLocations(origLat: coordinates.lat, origLon: coordinates.lon, newLat: mapCoord[key!]!.latitude, newLon: mapCoord[key!]!.longitude, id: key!, done: {distance in
                    busDistance[key!] = distance
                    
                })
            }
        })

调用RateLimiter的代码

let GlobalDirectionsRateLimiter = RateLimiter(tokensPerInterval: 50, interval: .minute)
        
        GlobalDirectionsRateLimiter.removeTokens(directionsChecked) {d in
            print(d)
            directions.calculate { (response, error) in
                if let response = response, let route = response.routes.first {
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "BusDataChanged"), object: nil)
                    done(route.distance/1609)
                } else {
                    print("ERROR getting distance \(String(describing: error))")
                    //busDistance[id] = route.distance/1609
                }
            }
        }

removeTokens()的实现代码

public func removeTokens(_ count: Double, callback: @escaping (Double) -> ()) {
        
        if count > bucket.sizeOfBucket {
            callback(-Double.infinity)

            return
        }
        
        let now = Date().timeIntervalSince1970

        if now - intervalStart >= bucket.interval {
            intervalStart = now
            tokensThisInterval = 0
        }

        guard count <= bucket.tokensPerInterval - tokensThisInterval else {
            if firesImmediatly {
                return callback(-Double.infinity)
            }

            queue.asyncAfter(deadline: DispatchTime.now() + ceil(intervalStart + bucket.interval - now)) {
                func afterBucketRemove(tokensRemaining: Double) {
                    self.tokensThisInterval += count

                    callback(tokensRemaining)
                }

                self.bucket.removeTokens(count, callback: afterBucketRemove)
            }

            return
        }

        func afterBucketRemove(tokensRemaining: Double) {
            tokensThisInterval += count

            callback(tokensRemaining)
        }

        return bucket.removeTokens(count, callback: afterBucketRemove)
    }

核心疑问

我理解GlobalDirectionsRateLimiter设置了每分钟最多允许50次请求,但对GlobalDirectionsRateLimiter.removeTokens(directionsChecked)这一行存在疑问:官方示例文档中该参数为硬编码数值,我将其设置为每次循环自增的directionsChecked变量(代表当前检查的请求计数),请问这种用法是否正确?


内容的提问来源于stack exchange,提问作者user22407520

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 08:47:03