促成的未来 1.0.2

PromisedFuture 1.0.2

Alaeddine Me维护。




  • 作者:
  • Alaeddine Messaoudi

logo


CI Status Version License Platform Carthage compatible

PromisedFuture

PromisedFuture 是对 Future/Promise 的轻量级实现。 PromisedFuture 有助于编写可读性和易于理解的异步代码。

通常在处理异步任务时使用回调机制。它在某些情况下应该能完成任务,但通常我们需要执行多个异步操作,因此我们必须在第一个操作的完成块中嵌套第二个操作。但是,当我们有嵌套的回调时,事情开始变得杂乱,代码在可维护性、可读性和控制方面不友好,从而导致“末日金字塔”、回调地狱和错误处理问题。

PromisedFuture 正在抢救,代码将从这个

APIClient.login(email: "[email protected]", password: "myPassword", completion: { result in
    switch result {
    case .success(let user):
        APIClient.userArticles(userID: user.id, completion: { result in
            switch result {
            case .success(let articles):
                APIClient.getArticle(id: articles.last!.id, completion: { result in
                    switch result {
                    case .success(let article):
                        print(article)
                    case .failure(let error):
                        print(error)
                    }
                })
            case .failure(let error):
                print(error)
            }
        })
    case .failure(let error):
        print(error)
    }
})

变到这个

APIClient.login(email: "[email protected]", password: "myPassword")
         .map({$0.id})
         .andThen(APIClient.userArticles)
         .map({$0.last!.id})
         .andThen(APIClient.getArticle)
         .execute(onSuccess: { article in
            print(article)
         }, onFailure: {error in
            print(error)
         })

功能

  • 可连`)可将异步操作链接起来。
  • 轻量级,易于使用(仅 ≈ 40 行代码)。
  • 完全测试单元。
  • 完整文档。

要求

  • iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+
  • Xcode 9.0+
  • Swift 4.0+

示例

要运行示例项目,请克隆仓库,然后打开工作区 PromisedFuture.xcworkspace,使用 iOS Example 方案运行。

安装

CocoaPods

CocoaPods 是 Cocoa 项目的依赖管理器。您可以使用以下命令安装它:

$ gem install cocoapods

要使用 CocoaPods 将 PromisedFuture 集成到您的 Xcode 项目中,请在您的 Podfile 中指定它:

use_frameworks!

pod 'PromisedFuture'

然后,运行以下命令:

$ pod install

Carthage

Carthage 是一个去中心化的依赖管理器,可构建您的依赖关系并提供二进制框架。

您可以使用以下命令使用 Homebrew 安装 Carthage:

$ brew update
$ brew install carthage

要使用 Carthage 将 PromisedFuture 集成到您的 Xcode 项目中,请在您的 Cartfile 中指定它:

github "aladinway/PromisedFuture"

运行 carthage update 来构建框架。然后在您的应用程序目标的“常规”设置选项卡中的“嵌入的二进制文件”部分,从磁盘上的 Carthage/Build 文件夹拖放构建的 PromisedFuture.framework

用法

创建一个 Future:

要用操作(例如网络调用)创建一个 Future,我们使用

init(operation: @escaping (_ completion:@escaping Completion) -> Void)

  • 参数
    • operation:Future 应该执行的操作。这通常是异步操作。
    • completion:操作的结果块。它有操作的 Result 作为参数。
  • 示例用法
let future = Future(operation: { completion in
// Your operation here to retrieve the value
Alamofire.request("https://httpbin.org/get")
    .responseData { response in
        switch response.result {
        case .success(let value):
		// Then in case of success you call the completion
		// with the Result passing the value
		completion(.success(data))
        case .failure(let error):
		// or in case of error call the completion
		// with the Result passing the error like :
		//completion(.failure(error))
        }
    }
})

您也可以通过 ResultValueError 来创建一个 Future

使用提供的 Result 初始化一个新的 Future

init(result: Result<Value>)

  • 参数

    • result:Future 的结果。它可以是一个包含值的成功 Result 或包含 Error 的失败。
  • 示例用法

let future = Future(result: Result.success(12))

使用提供的值初始化一个新的 Future

init(value: Value)

  • 参数

    • value:Future 的值。
  • 示例用法

let future = Future(value: "Hello")

使用提供的 Error 初始化一个新的 Future

init(value: Value)

  • 参数

    • value:Future 的值。
  • 示例用法

let f: Future<Int>= Future(error: NSError(domain: "E", code: 4, userInfo: nil))

执行一个 Future:

要执行 Future 的操作,我们可以使用以下这些方法

  • func execute(completion: @escaping Completion)

    • 参数
      • completion:操作的结果块。它有操作的 Result 作为参数。
  • 示例用法

     let future = Future(value: 14)
     future.execute(completion: { result in
        switch result {
        case .success(let value):
            print(value) // it will print 14
        case .failure(let error):
            print(error)
        }
     })
  • func execute(completion: @escaping Completion)

    • 参数
      • onSuccess:操作的成功能域块。它作为操作的值参数。
      • onFailure:操作的失败能域块。它作为操作的错误参数。
  • 示例用法

     let future = Future(value: 14)
     future.execute(onSuccess: { value in
        print(value) // it will print 14
     }, onFailure: { error in
        print(error)
     })

链式调用多个 Future:

Future 的强大之处在于可以链式调用异步操作。我们可以使用 andThen 方法链式调用两个依赖于 futures。

  • func andThen<U>(_ f: @escaping (_ value: Value) -> Future<U>) -> Future<U>

    • 参数
      • f:一个通过传递此 Future 的值来生成新的 Future 的函数。
  • 示例用法

     struct User {
        id: Int
     }
    
     // Let's assume we need to perform two network operations
     // The first one to get the user id
     // And the second one to get the user information
     // we can use `andThen` to chain them
    
     let userIdFuture = Future(value: 14)
    
     func userFuture(by userId: Int) -> Future<User> {
        return Future(value: User(id: userId))
     }
    
     userIdFuture.andThen(userFuture).execute { user in
        print(user)
     }

    我们还可以使用 map 函数将 Future 的结果进行映射

    • func map<T>(_ f: @escaping (_ value: Value) -> T) -> Future<T>
  • 参数

    • f:一个通过传递此 Future 的值来生成新的 Future 的函数
  • 示例用法

     let stringFuture = Future(value: "http://www.google.com")
     let urlFuture = stringFuture.map({URL(string: $0)})

阅读

如果您想了解更多关于 Futures 以及如何在网络层中使用 PromisedFutureAlamofire 一起,强烈推荐阅读我的以下文章:

使用 Alamofire 5 和 Codable 在 Swift 4 中编写网络层第 3 部分:使用 Futures/Promises

作者

Alaeddine Messaoudi [email protected]

许可

PromisedFuture 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。