PromiseKit 使用

作者: xiAo__Ju | 来源:发表于2017-06-04 16:32 被阅读4528次

    看到这样的代码你的内心应该是一万匹草泥马跑过了吧!

    Alamofire.request(url, method: .get).responseJSON { response in
                switch response.result {
                case .success(_):
                    Alamofire.request(url1, method: .get).responseJSON { response in
                        switch response.result {
                        case .success(_):
                            Alamofire.request(url2, method: .get).responseJSON { response in
                                switch response.result {
                                case .success(_):
                                    doSomething()
                                case .failure(_):
                                    print("XXX错误")
                                }
                            }
                        case .failure(_):
                            print("XXX错误")
                        }
                    }
                case .failure(_):
                    print("XXX错误")
                }
            }
    

    你内心的代码肯定应该是这样的

       func request(with parameters: [String: Any]) -> Promise<NSDictionary> {
            return Promise { fulfill, reject in
                Alamofire.request("https://httpbin.org/get", method: .get, parameters: parameters).validate().responseJSON() { (response) in
                    switch response.result {
                    case .success(let dict):
                        fulfill(dict as! NSDictionary)
                    case .failure(let error):
                        reject(error)
                    }
                }
            }
        }
    
        func threeRequest() -> Promise<()> {
            return firstly {
                    request(with: ["test1": "first"])
                }.then { (v) -> Promise<NSDictionary> in
                    print("🍀", v)
                    return self.request(with: ["test2": "second"])
                }.then { (v) -> Promise<NSDictionary> in
                    print("🍀🍀", v)
                    return self.request(with: ["test3": "third"])
                }.then { (v) in
                    print("🍀🍀🍀", v)
                }.catch { (error) in
                    print(error)
                }
        }
    

    她优雅,干净,易懂。如同初恋一般美好。
    那么怎样才能写出这样干净、易懂的代码呢?

    今天给大家分享一个神器—PromiseKit

    基本使用

    Promise { fulfill, reject in
                Alamofire.request("https://httpbin.org/get", method: .get, parameters: parameters).validate().responseJSON() { (response) in
                    switch response.result {
                    case .success(let dict):
                        fulfill(dict as! NSDictionary)
                    case .failure(let error):
                        reject(error)
                    }
                }
           }.then { dict in
                 print(dict)
           }.catch { (error) in
                  print(error)
           }
    

    如果你看过函数式 Swift这本书应该对Promise这种样子很熟,只不过这里是两个回调,书中的例子都只有一个回调。

    • fulfill(履行):将结果传递到then分支
    • reject (拒绝):将结果传递到catch分支
      是不是感觉很人性化,一个承诺,要么履行,要么拒绝。

    firstly

    文档解释

    Compare:
    
         NSURLSession.GET(url1).then {
             NSURLSession.GET(url2)
         }.then {
             NSURLSession.GET(url3)
         }
    
     With:
    
         firstly {
             NSURLSession.GET(url1)
         }.then {
             NSURLSession.GET(url2)
         }.then {
             NSURLSession.GET(url3)
         }
    

    其实作用就是让风格更优雅

    always

    从字面意思就可以理解总是都会执行,你可以用在任意位置

    firstly {
                session()
    }.then { data in
      Promise<[String: Any]> { (fulfill, reject) in
       do {
          let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
              fulfill(json as! [String : Any])
           } catch {
               reject(error)
           }
      }
    }.always {
        print("1111")
    }.then { (json) in
        print(json)
    }.always {
        print("always", Thread.current)
    }.catch { (error) in
        print(error)
    }.always {
        print("😁")
     }
    

    when

    when(fulfilled: sessionPromise(), loginPromise()).then { (data, dict) in
        print(data, dict)
    }.catch { error in
        print(error)
    }
    

    你可以同时执行多个Promise,最终会掉到一个then

    race

    字面意思比赛

    race(loginPromise(), loginPromise()).then { winner in
       print(winner)
    }.catch { error in
       print(error)
    }
    

    他同when的区别:

    • 只有最快的那个会掉到then
    • Promise的泛型必须相同

    then

    firstly {
                sessionPromise()
            }.then(on: DispatchQueue.global()) { data -> Promise<[String: Any]> in
                print("global queue", Thread.current)
                return Promise<[String: Any]> { (fulfill, reject) in
                    do {
                        let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
                            fulfill(json as! [String : Any])
                    } catch {
                            reject(error)
                    }
                }
            }.always {
                print("1111", Thread.current)
            }.then { (json) in
                print(json, Thread.current)
            }.always {
                print("always", Thread.current)
            }.catch { (error) in
                print(error)
            }.always {
                print("😁")
            }
    

    解释接收fulfill分支的回调的,你可以指定当前then分支执行的队列

    wrap

    文档说:
    However you inevitably use some other framework that doesn’t support promises. For these situations we provide PromiseKit.wrap

    就是不支持promises的用这个,没大理解,有用个的朋友回复一下,谢谢

    FAQ

    1. 什么是Promise?
      Promise 是一种链接异步任务的方式。通常来说,异步任务会在异步操作完成时执行回调闭包(有时候要准备两个闭包,一个代表成功,一个代表失败)
    2. Promise的原理?
      Promise 本质上是状态机
      Promise 是一个 Monad
    3. Promise的来源?
      Promise 在 JavaScript 社区中反响热烈。因为 Node.js 的设计中包含了非常多异步操作,即便是简单的任务也需要用到链式的异步回调。即便只有三、四个这样的操作,代码会变得笨重。Promise 终结了提心吊胆写回调的日子,Promise 已经写进了 JavaScript ES6 的规范。这篇博客介绍了 JavaScript Promise 的运作机制。

    尾巴

    如果使用了PromiseKit,你觉得你的代码还不够优雅,那么在再你推荐两个库:
    Result
    Moya

    推荐文章

    RxSwift vs PromiseKit
    Getting Started with PromiseKit
    Swift 中的 Promise
    Promise 的几种通用模式
    状态模式

    本文测试Demo

    相关文章

      网友评论

        本文标题:PromiseKit 使用

        本文链接:https://www.haomeiwen.com/subject/yfsvfxtx.html