Alamofire 浅析 <五> 使用OperationQueue实现类似promise的机制

response使用示例:


        let urlString = "https://invalid-url-here.org/this/does/not/exist"
        SessionManager.default.request(URL.init(string: urlString)!)
            .responseData { result in
                print("\(result)")
        }

// response  core code
    @discardableResult
    public func response(
        queue: DispatchQueue? = nil,
        responseSerializer: T,
        completionHandler: @escaping (DataResponse) -> Void)
        -> Self
    {
        delegate.queue.addOperation {
            let result = responseSerializer.serializeResponse(
                self.request,
                self.response,
                self.delegate.data,
                self.delegate.error
            )

            var dataResponse = DataResponse(
                request: self.request,
                response: self.response,
                data: self.delegate.data,
                result: result,
                timeline: self.timeline
            )

            dataResponse.add(self.delegate.metrics)

            (queue ?? DispatchQueue.main).async { completionHandler(dataResponse) }
        }

        return self
    }
    
  // DownloadResponseSerializerProtocol
  
  public protocol DownloadResponseSerializerProtocol {
    /// The type of serialized object to be created by this `DownloadResponseSerializerType`.
    associatedtype SerializedObject

    /// A closure used by response handlers that takes a request, response, url and error and returns a result.
    var serializeResponse: (URLRequest?, HTTPURLResponse?, URL?, Error?) -> Result { get }
}
    
  • 利用闭包延时求值
  let result = responseSerializer.serializeResponse(
                self.request,
                self.response,
                self.delegate.data,
                self.delegate.error
            )

result 是一个闭包,只有这个闭包在执行的时候才会获取self.request的值,这样相比传统的直接赋值的好处在于,如果self.request更新了,闭包执行的时候永远是获取最新的request值。

  • 它是怎么工作的?
    通常一个闭包被提交到OperationQueue的时候,会立马执行,那么按照这个逻辑request请求还没发送,或者还在传输的时候,你执行这个block有什么意义呢?里面没有任何数据。这就是有意思的地方,Request 在初始化的时候OperationQueue.isSuspended = true, 这样这个闭包会一直被挂起不会执行,直到Request收到sessionDidComplete信息的时候才会将其置为false,这时闭包执行,这样就能保证无论你在什么时候调用responseData,在session发起之前,之间,之后,得到的response是一样的,达到promise效果。

你可能感兴趣的:(Alamofire 浅析 <五> 使用OperationQueue实现类似promise的机制)