When

CI Status Version Carthage Compatible License Platform

描述

When 是 Swift 中 Promises 的轻量级实现。它不包含任何用于 iOS 和 OSX 的辅助函数,这是有意为之,旨在消除冗余的复杂性,并在您的选择中给予您更多的自由和灵活性。 感谢 Swift 泛型,它是类型安全的,因此您可以创建具有任何您想要的类型的 promises

When 可以轻松集成到您的项目和库中,将您的异步代码提升到新的水平。

目录

When Icon

为什么?

为了使异步代码更具可读性和标准化

fetchJSON().then({ data: NSData -> [[String: AnyObject]] in
  // Convert to JSON
  return json
}).then({ json: [[String: AnyObject]] -> [Entity] in
  // Map JSON
  // Save to database
  return items
}).done({ items: [Entity] in
  self.items = items
  self.tableView.reloadData()
}).error({ error in
  print(error)
})

用法

Promise (承诺)

一个 promise 代表一个任务的未来值。 Promises 从挂起状态开始,然后可以解析为一个值或拒绝为一个错误。

// Creates a new promise that could be resolved with a String value
let promise = Promise<String>()
// Resolves the promise
promise.resolve("String")
// Or rejects the promise
promise.reject(Error.notFound)
// Creates a new promise that is resolved with a String value
let promise = Promise({
  return "String"
})
// Creates a new promise that is rejected with an Error
let promise = Promise({
  //...
  throw Error.notFound
})

当前 promise 和所有链式 promise (使用 then 创建) 的回调默认在主队列上执行,但您始终可以在 init 中指定所需的队列

let promise = Promise<String>(queue: dispatch_get_main_queue())

Done (完成)

添加一个处理程序,当 promise 对象被解析为一个值时调用

// Create a new promise in a pending state
let promise = Promise<String>()
// Add done callback
promise.done({ value in
  print(value)
})
// Resolve the promise
promise.resolve("String")

Fail (失败)

添加一个处理程序,当 promise 对象被拒绝并返回一个 Error 时调用

// Create a new promise in a pending state
let promise = Promise<String>()
// Add fail callback
promise.fail({ error in
  print(error)
})
// Reject the promise
promise.reject(Error.notFound)

也可以取消 promise,这意味着它将被拒绝并返回 PromiseError.cancelled 错误。 如果您想在 fail 处理程序中忽略此错误,可以使用 FailurePolicy

// Create a new promise in a pending state
let promise = Promise<String>()
// This callback will not be called when a promise is cancelled
promise.fail({ error in
  print(error)
})
// This callback will be called when a promise is cancelled
promise.fail(policy: .allErrors, { error in
  print(error)
})
// Cancel the promise
promise.cancel()

Always (总是)

添加一个处理程序,当 promise 对象被解析或拒绝时调用。 此回调将在 donefail 处理程序之后调用。

// Create a new promise in a pending state
let promise = Promise<String>()
// Add always callback
promise.always({ result in
  switch result {
  case let .success(value):
    print(value)
  case let .failure(error):
    print(error)
  }
})
// Resolve or reject the promise
promise.resolve("String") // promise.reject(Error.notFound)

Then (然后)

返回一个新的 promise,它可以使用当前 promise 的结果值。 这意味着您可以轻松创建 promises 链,以将复杂的异步操作简化为清晰易懂的逻辑。

一个新的 promise 将被解析为从提供的闭包返回的值

let promise = Promise<NSData>()

promise
  .then({ data -> Int in
    return data.length
  }).then({ length -> Bool in
    return length > 5
  }).done({ value in
    print(value)
  })

promise.resolve("String".dataUsingEncoding(NSUTF8StringEncoding)!)

当从提供的闭包返回的 promise 解析时,一个新的 promise 将被解析

struct Networking {
  static func GET(url: NSURL) -> Promise<NSData> {
    let promise = Promise<NSData>()
    //...
    return promise
  }
}

Networking.GET(url1)
  .then({ data -> Promise<NSData> in
    //...
    return Networking.GET(url2)
  }).then({ data -> Int in
    return data.length
  }).done({ value in
    print(value)
  })

then 闭包默认在主队列上执行,但您可以传递所需的队列作为参数

promise.then(on: dispatch_get_global_queue(QOS_CLASS_UTILITY, 0))({ data -> Int in
  //...
})

如果您想使用后台队列,这里有针对这种情况的辅助方法

promise1.thenInBackground({ data -> Int in
  //...
})

promise2.thenInBackground({ data -> Promise<NSData> in
  //...
})

Recover (恢复)

返回一个新的 promise,当抛出错误时,可以使用它来继续链式调用。

let promise = Promise<String>()
// Recover the chain
promise
  .recover({ error -> Promise<String> in
    return Promise({
      return "Recovered"
    })
  })
  .done({ string in
    print(string) // Recovered
  })
// Reject the promise
promise.reject(Error.notFound)

When (当)

提供了一种基于一个或多个 promises 执行回调函数的方法。 when 方法返回一个新的“主” promise,用于跟踪所有传递的 promises 的聚合状态。 该方法将在所有 promises 都解析后立即解析其“主” promise,或者在其中一个 promises 被拒绝后立即拒绝“主” promise。 如果“主” promise 被解析,则将使用每个 promises 的已解析值执行 done 回调

let promise1 = Promise<Int>()
let promise2 = Promise<String>()
let promise3 = Promise<Int>()

when(promise1, promise2, promise3)
  .done({ value1, value2, value3 in
    print(value1)
    print(value2)
    print(value3)
  })

promise1.resolve(1)
promise2.resolve("String")
promise3.resolve(3)

Reactive extensions (响应式扩展)

为了将 WhenRxSwift 集成,请使用以下扩展

import RxSwift

extension Promise: ObservableConvertibleType {
  public func asObservable() -> Observable<T> {
    return Observable.create({ observer in
      self
        .done({ value in
          observer.onNext(value)
        })
        .fail({ error in
          observer.onError(error)
        })
        .always({ _ in
          observer.onCompleted()
        })

      return Disposables.create()
    })
  }
}

安装

When 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到您的 Podfile

pod 'When'

对于 RxSwift 扩展,您可以使用 CocoaPods subspecs

pod 'When/RxSwift'

When 也可通过 Carthage 获得。 要安装,只需写入您的 Cartfile

github "vadymmarkov/When"

作者

Vadym Markov, markov.vadym@gmail.com

致谢

灵感归功于 PromiseKitThen

贡献

查看 CONTRIBUTING 文件以获取更多信息。

许可

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