【问题标题】:Alamofire number of requests one after anotherAlamofire 请求数量一个接一个
【发布时间】:2016-12-02 12:36:37
【问题描述】:

我有许多请求,我想在没有嵌套意大利面条代码的情况下一个接一个地调用。

我已经用串行调度队列试过了

let queue = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL)

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
            print(1)
        }

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
            print(2)
        }

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
            print(3)
        }

但不幸的是,这不起作用。其输出可以是 1,3,2 或 3,1,2 或任何其他组合。

依次获得输出 1、2、3 的最佳方法是什么。

【问题讨论】:

  • 你是否有 n 次尝试,或者你已经知道你将有多少请求?
  • 我知道我有多少,但当然最好是动态的
  • 您尝试过使用dispatch_semaphore 吗?我实际上没有时间回复一个好的答案,但是您可以在 SO 中找到很多示例
  • Alamofire 只支持dispatch_queue_t :/

标签: swift io alamofire


【解决方案1】:

好的,我最终编写了自己的实现。

我创建了一个类RequestChain,它以Alamofire.Request 作为参数

class RequestChain {
    typealias CompletionHandler = (success:Bool, errorResult:ErrorResult?) -> Void

    struct ErrorResult {
        let request:Request?
        let error:ErrorType?
    }

    private var requests:[Request] = []

    init(requests:[Request]) {
        self.requests = requests
    }

    func start(completionHandler:CompletionHandler) {
        if let request = requests.first {
            request.response(completionHandler: { (_, _, _, error) in
                if error != nil {
                    completionHandler(success: false, errorResult: ErrorResult(request: request, error: error))
                    return
                }
                self.requests.removeFirst()
                self.start(completionHandler)
            })
            request.resume()
        }else {
            completionHandler(success: true, errorResult: nil)
            return
        }

    }
}

我是这样用的

let r1 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in
    print("1")
}

let r2 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in
    print("2")
}

let r3 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in
    print("3")
}

let chain = RequestChain(requests: [r1,r2,r3])

chain.start { (success, errorResult) in
    if success {
        print("all have been success")
    }else {
        print("failed with error \(errorResult?.error) for request \(errorResult?.request)")
    }


}

重要的是你告诉经理不要立即执行请求

    let manager = Manager.sharedInstance
    manager.startRequestsImmediately = false

希望对别人有所帮助

【讨论】:

    【解决方案2】:

    我使用Artman's Signals 在返回结果后通知我的应用程序,之后其他地方的队列可以调用它的下一个请求:

    Alamofire.request( httpMethod, url, parameters: params ).responseJSON
    {
        ( response: Response< AnyObject, NSError > ) in
    
        self._signals.dispatchSignalFor( Key: url, data: response.result )
    }
    

    更多详情here

    【讨论】:

    • 有趣的方法!感谢这次成功,但它不适合我的代码库。谢谢
    【解决方案3】:

    一种解决方案是在第一个回调中调用您的第二个请求:

    Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
                print(1)
                Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
                     print(2)
                     Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in
                          print(3)
                     }
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-16
      • 2015-04-22
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      相关资源
      最近更新 更多