Compare commits
11 Commits
fix-NSErro
...
v4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47f40ef75f | ||
|
|
dd77da78cb | ||
|
|
1001d23725 | ||
|
|
a92c40ca73 | ||
|
|
7fb12976da | ||
|
|
99771a775e | ||
|
|
c70677a12b | ||
|
|
de638abca5 | ||
|
|
52697b25d4 | ||
|
|
6bab5e0c7f | ||
|
|
d7a978d628 |
119
.travis.yml
119
.travis.yml
@ -1,5 +1,90 @@
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode10.1
|
||||
env: SWFT=4.2 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode10.1
|
||||
env: SWFT=4.2 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode10.1
|
||||
env: SWFT=4.2 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode10.1
|
||||
env: SWFT=4.2 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=4.1 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=4.1 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=4.1 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=4.1 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=3.2 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=3.2 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=3.2 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.3
|
||||
env: SWFT=3.2 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=4.0 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=4.0 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=4.0 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=4.0 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=3.2 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=3.2 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=3.2 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.2
|
||||
env: SWFT=3.2 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.1
|
||||
@ -34,6 +119,40 @@ matrix:
|
||||
osx_image: xcode9.1
|
||||
env: SWFT=3.2 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=4.0 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=4.0 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=4.0 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=4.0 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=3.2 PLAT=macOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=3.2 PLAT=iOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=3.2 PLAT=tvOS
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode9.0
|
||||
env: SWFT=3.2 PLAT=watchOS
|
||||
|
||||
- os: osx
|
||||
language: objective-c
|
||||
osx_image: xcode8.3
|
||||
|
||||
@ -342,7 +342,7 @@ is more thorough at the source.
|
||||
In Xcode don’t forget to `⌥` click on PromiseKit functions to get at this
|
||||
documentation while you are developing.
|
||||
|
||||
Otherwise return to our [contents page](/Documentation).
|
||||
Otherwise return to our [contents page](..).
|
||||
|
||||
|
||||
[sources]: https://github.com/mxcl/PromiseKit/tree/master/Sources
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Xcode 8 or 9 / Swift 3 or 4
|
||||
# Xcode 8, 9 or 10 / Swift 3 or 4
|
||||
|
||||
We recommend CocoaPods.
|
||||
|
||||
@ -46,8 +46,7 @@ PromiseKit contains Swift, so there have been rev-lock issues with Xcode:
|
||||
|
||||
| PromiseKit | Swift | Xcode | CI Status | Release Notes |
|
||||
| ---------- | -------- | -------- | ------------ | ----------------- |
|
||||
| 5 | 3.x, 4.x | 8.x, 9.x | ![ci-master] | In beta |
|
||||
| 4 | 3.x, 4.x | 8.x, 9.x | ![ci-master] | [2016/09][news-4] |
|
||||
| 4 | 3.x, 4.x | 8.x, 9.x, 10.1 | ![ci-master] | [2016/09][news-4] |
|
||||
| 3 | 2.x | 7.x, 8.0 | ![ci-swift2] | [2015/10][news-3] |
|
||||
| 2 | 1.x | 7.x | Unsupported | [2015/10][news-3] |
|
||||
| 1† | *N/A* | * | ![ci-legacy] | – |
|
||||
@ -82,12 +81,6 @@ pod "PromiseKit", "~> 3.5"
|
||||
github "mxcl/PromiseKit" ~> 3.5
|
||||
```
|
||||
|
||||
|
||||
# PromiseKit 5
|
||||
|
||||
[PromiseKit 5 is experimental and under active development](https://github.com/mxcl/PromiseKit/tree/experimental-5.x).
|
||||
|
||||
|
||||
[travis]: https://travis-ci.org/mxcl/PromiseKit
|
||||
[ci-master]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master
|
||||
[ci-legacy]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=legacy-1.x
|
||||
@ -96,7 +89,7 @@ github "mxcl/PromiseKit" ~> 3.5
|
||||
[ci-22]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.2-minimal-changes
|
||||
[ci-20]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.0-minimal-changes
|
||||
[news-2]: http://promisekit.org/news/2015/05/PromiseKit-2.0-Released/
|
||||
[news-3]: https://github.com/mxcl/PromiseKit/blob/master/CHANGELOG.markdown#300-oct-1st-2015
|
||||
[news-3]: https://github.com/mxcl/PromiseKit/blob/212f31f41864d1e3ec54f5dd529bd8e1e5697024/CHANGELOG.markdown#300-oct-1st-2015
|
||||
[news-4]: http://promisekit.org/news/2016/09/PromiseKit-4.0-Released/
|
||||
[swift-2.3-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.3-minimal-changes
|
||||
[swift-2.2-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.2-minimal-changes
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Contents
|
||||
|
||||
* [README](/README.md)
|
||||
* [README](../README.md)
|
||||
* Handbook
|
||||
* [Getting Started](GettingStarted.md)
|
||||
* [Promises: Common Patterns](CommonPatterns.md)
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 2d9497395350fd0219ba7b62ac08b55f0d2c7cdb
|
||||
Subproject commit 5636e88018ee9cfcea68bccd39f74409c1faea53
|
||||
@ -1 +1 @@
|
||||
Subproject commit 111d2b4fedd8729c2bb9deabc04b03bb1f47dcdb
|
||||
Subproject commit ac0e2140d57c0193222582872586bf3ff30cc634
|
||||
@ -1 +1 @@
|
||||
Subproject commit a56c183961d1bfe368df40804544b968eb84e0f9
|
||||
Subproject commit 0e1d5981ebfb495062cc61368edb2d46e8831cf5
|
||||
@ -509,7 +509,7 @@
|
||||
6399A3721D595D9100D65233 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1000;
|
||||
TargetAttributes = {
|
||||
630019011D596292003B4E30 = {
|
||||
LastSwiftMigration = 0900;
|
||||
@ -773,12 +773,14 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -787,7 +789,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 4.4.4;
|
||||
CURRENT_PROJECT_VERSION = 4.5.2;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@ -831,12 +833,14 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
@ -845,7 +849,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 4.4.4;
|
||||
CURRENT_PROJECT_VERSION = 4.5.2;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "1000"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
@ -96,7 +95,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||

|
||||

|
||||
|
||||
![badge-pod] ![badge-languages] ![badge-pms] ![badge-platforms] [](https://travis-ci.org/mxcl/PromiseKit)
|
||||
|
||||
[繁體中文](README.zh_Hant.md), [简体中文](README.zh_CN.md)
|
||||
![badge-pod][] ![badge-languages][] ![badge-pms][] ![badge-platforms][] [](https://travis-ci.org/mxcl/PromiseKit)
|
||||
|
||||
---
|
||||
|
||||
@ -41,7 +39,7 @@ target "Change Me!" do
|
||||
end
|
||||
```
|
||||
|
||||
PromiseKit 4 supports Xcode 8.1, 8.2, 8.3 and 9.0; Swift 3.0, 3.1, 3.2 and 4.0; iOS, macOS, tvOS, watchOS, Linux and Android; CocoaPods, Carthage and SwiftPM; ([CI Matrix](https://travis-ci.org/mxcl/PromiseKit)).
|
||||
PromiseKit 4 supports Xcode 8.1, 8.2, 8.3, 9.0, 9.1, 9.2, 10.0 and 10.1; Swift 3.0, 3.1, 3.3, 4.0, 4.1 and 4.2; iOS, macOS, tvOS, watchOS, Linux and Android; CocoaPods, Carthage and SwiftPM; ([CI Matrix](https://travis-ci.org/mxcl/PromiseKit)).
|
||||
|
||||
For Carthage, SwiftPM, etc., or for instructions when using older Swifts or
|
||||
Xcodes see our [Installation Guide](Documentation/Installation.md).
|
||||
|
||||
238
README.zh_CN.md
238
README.zh_CN.md
@ -1,238 +0,0 @@
|
||||

|
||||
|
||||
![badge-pod] ![badge-languages] ![badge-pms] ![badge-platforms] ![badge-mit]
|
||||
|
||||
[English](README.markdown)
|
||||
|
||||
---
|
||||
|
||||
现代编程语言都很好的支持了异步编程,因此在 swift 编程中,拥有功能强大且轻量级的异步编程工具的需求变得很强烈。
|
||||
|
||||
```swift
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
||||
|
||||
firstly {
|
||||
when(URLSession.dataTask(with: url).asImage(), CLLocationManager.promise())
|
||||
}.then { image, location -> Void in
|
||||
self.imageView.image = image;
|
||||
self.label.text = "\(location)"
|
||||
}.always {
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
||||
}.catch { error in
|
||||
UIAlertView(/*…*/).show()
|
||||
}
|
||||
```
|
||||
PromiseKit 是一款 swift 编写的支持 iOS,macOS,tvOS,watchOS 等多平台的轻量级异步编程库,同时 PromiseKit 完美的支持了 Objective-C 桥接。
|
||||
|
||||
# 快速预览
|
||||
|
||||
我们推荐您使用 [CocoaPods] 或者 [Carthage] 来集成 PromiseKit,您也可以通过把 `PromiseKit.xcodeproj` 拖拽到项目中并导入 `PromiseKit.framework` 来手动集成。
|
||||
|
||||
## Xcode 8 / Swift 3
|
||||
|
||||
```ruby
|
||||
# CocoaPods >= 1.1.0-rc.2
|
||||
swift_version = "3.0"
|
||||
pod "PromiseKit", "~> 4.0"
|
||||
|
||||
# Carthage
|
||||
github "mxcl/PromiseKit" ~> 4.0
|
||||
|
||||
# SwiftPM
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.Package(url: "https://github.com/mxcl/PromiseKit", majorVersion: 4)
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Xcode 8 / Swift 2.3 or Xcode 7
|
||||
|
||||
```ruby
|
||||
# CocoaPods
|
||||
swift_version = "2.3"
|
||||
pod "PromiseKit", "~> 3.5"
|
||||
|
||||
# Carthage
|
||||
github "mxcl/PromiseKit" ~> 3.5
|
||||
```
|
||||
|
||||
# 文档
|
||||
|
||||
您可以通过 [promisekit.org] 站点来查看全部文档
|
||||
|
||||
## 概览
|
||||
|
||||
在 `then` 方法中定义异步任务:
|
||||
|
||||
```swift
|
||||
login().then { json in
|
||||
//…
|
||||
}
|
||||
```
|
||||
|
||||
链式调用:
|
||||
|
||||
```swift
|
||||
login().then { json -> Promise<UIImage> in
|
||||
return fetchAvatar(json["username"])
|
||||
}.then { avatarImage in
|
||||
self.imageView.image = avatarImage
|
||||
}
|
||||
```
|
||||
|
||||
`catch` 链式调用进行错误处理:
|
||||
|
||||
```swift
|
||||
login().then {
|
||||
return fetchAvatar()
|
||||
}.then { avatarImage in
|
||||
//…
|
||||
}.catch { error in
|
||||
UIAlertView(/*…*/).show()
|
||||
}
|
||||
```
|
||||
|
||||
组合调用:
|
||||
|
||||
```swift
|
||||
let username = login().then{ $0["username"] }
|
||||
|
||||
when(username, CLLocationManager.promise()).then { user, location in
|
||||
return fetchAvatar(user, location: location)
|
||||
}.then { image in
|
||||
//…
|
||||
}
|
||||
```
|
||||
|
||||
简单重构:
|
||||
|
||||
```swift
|
||||
func avatar() -> Promise<UIImage> {
|
||||
let username = login().then{ $0["username"] }
|
||||
|
||||
return when(username, CLLocationManager.promise()).then { user, location in
|
||||
return fetchAvatar(user, location: location)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
您也可以创建一个新的异步任务:
|
||||
|
||||
```swift
|
||||
func fetchAvatar(user: String) -> Promise<UIImage> {
|
||||
return Promise { fulfill, reject in
|
||||
MyWebHelper.GET("\(user)/avatar") { data, err in
|
||||
guard let data = data else { return reject(err) }
|
||||
guard let img = UIImage(data: data) else { return reject(MyError.InvalidImage) }
|
||||
guard let img.size.width > 0 else { return reject(MyError.ImageTooSmall) }
|
||||
fulfill(img)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 更多用法
|
||||
|
||||
您可以通过 [promisekit.org] 站点获得更多用法。
|
||||
|
||||
## PromiseKit vs. Xcode
|
||||
|
||||
由于 Xcode 支持不同版本的 swift,下面是 PromiseKit 与 Xcode 的对应关系:
|
||||
|
||||
| Swift | Xcode | PromiseKit | CI Status | Release Notes |
|
||||
| ----- | ----- | ---------- | ------------ | ----------------- |
|
||||
| 3 | 8 | 4 | ![ci-master] | [2016/09][news-4] |
|
||||
| 2 | 7/8 | 3 | ![ci-swift2] | [2015/10][news-3] |
|
||||
| 1 | 7 | 3 | – | [2015/10][news-3] |
|
||||
| *N/A* | * | 1† | ![ci-legacy] | – |
|
||||
|
||||
† PromiseKit 1 是纯 Objective-C 开发的,因此您可以在 Xcode 的任何版本中使用,当需要支持 iOS 7 或更低版本时只能选择 PromiseKit 1。
|
||||
|
||||
---
|
||||
|
||||
我们同时维护了一些分支来帮助您做 Swift 版本间的移植:
|
||||
|
||||
|
||||
| Xcode | Swift | PromiseKit | Branch | CI Status |
|
||||
| ----- | ----- | -----------| --------------------------- | --------- |
|
||||
| 8.0 | 2.3 | 2 | [swift-2.3-minimal-changes] | ![ci-23] |
|
||||
| 7.3 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
||||
| 7.2 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
||||
| 7.1 | 2.1 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
||||
| 7.0 | 2.0 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
||||
|
||||
我们通常不会再对这些分支做维护,但同样欢迎提交 PR。
|
||||
|
||||
# 扩展
|
||||
|
||||
Promises 仅在执行异步任务时非常有用,因此我们把苹果绝大部分接口都转换成了异步任务。当导入 Promises 时已经默认包含了 UIKit 和 Foundation。其他框架需要在 `Podfile` 中单独声明:
|
||||
|
||||
```ruby
|
||||
pod "PromiseKit/MapKit" # MKDirections().promise().then { /*…*/ }
|
||||
pod "PromiseKit/CoreLocation" # CLLocationManager.promise().then { /*…*/ }
|
||||
```
|
||||
|
||||
扩展的所有 repo 请访问 [PromiseKit org ](https://github.com/PromiseKit)。
|
||||
|
||||
在 `Cartfile` 中声明:
|
||||
|
||||
```ruby
|
||||
github "PromiseKit/MapKit" ~> 1.0
|
||||
```
|
||||
|
||||
## 选择网络库
|
||||
|
||||
直接使用 `URLSession` 通常是不可取的,您可以选择使用 [Alamofire] or [OMGHTTPURLRQ]:
|
||||
|
||||
```swift
|
||||
// pod 'PromiseKit/Alamofire'
|
||||
Alamofire.request("http://example.com", withMethod: .GET).responseJSON().then { json in
|
||||
//…
|
||||
}.catch { error in
|
||||
//…
|
||||
}
|
||||
|
||||
// pod 'PromiseKit/OMGHTTPURLRQ'
|
||||
URLSession.GET("http://example.com").asDictionary().then { json in
|
||||
|
||||
}.catch { error in
|
||||
//…
|
||||
}
|
||||
```
|
||||
[AFNetworking] 我们推荐使用 [csotiriou/AFNetworking]。
|
||||
|
||||
# 需要将您的代码转换到 Promises?
|
||||
|
||||
[有偿帮助](mailto:mxcl@me.com),我有几年 Promises 编码经验并在移动开发领域已有 10 年的开发经验。
|
||||
|
||||
# 支持
|
||||
|
||||
如果您有任何问题可以访问 [Gitter chat channel](https://gitter.im/mxcl/PromiseKit),也可以进行 [bug 追踪](https://github.com/mxcl/PromiseKit/issues/new)
|
||||
|
||||
|
||||
[travis]: https://travis-ci.org/mxcl/PromiseKit
|
||||
[ci-master]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master
|
||||
[ci-legacy]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=legacy-1.x
|
||||
[ci-swift2]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.x
|
||||
[ci-23]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.3-minimal-changes
|
||||
[ci-22]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.2-minimal-changes
|
||||
[ci-20]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.0-minimal-changes
|
||||
[news-2]: http://promisekit.org/news/2015/05/PromiseKit-2.0-Released/
|
||||
[news-3]: https://github.com/mxcl/PromiseKit/blob/master/CHANGELOG.markdown#300-oct-1st-2015
|
||||
[news-4]: http://promisekit.org/news/2016/09/PromiseKit-4.0-Released/
|
||||
[swift-2.3-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.3-minimal-changes
|
||||
[swift-2.2-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.2-minimal-changes
|
||||
[swift-2.0-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes
|
||||
[promisekit.org]: http://promisekit.org/docs/
|
||||
[badge-pod]: https://img.shields.io/cocoapods/v/PromiseKit.svg?label=version
|
||||
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20watchOS%20%7C%20tvOS-lightgrey.svg
|
||||
[badge-languages]: https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg
|
||||
[badge-mit]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[badge-pms]: https://img.shields.io/badge/supports-CocoaPods%20%7C%20Carthage%20%7C%20SwiftPM-green.svg
|
||||
[OMGHTTPURLRQ]: https://github.com/mxcl/OMGHTTPURLRQ
|
||||
[Alamofire]: http://alamofire.org
|
||||
[AFNetworking]: https://github.com/AFNetworking/AFNetworking
|
||||
[csotiriou/AFNetworking]: https://github.com/csotiriou/AFNetworking-PromiseKit
|
||||
[CocoaPods]: http://cocoapods.org
|
||||
[Carthage]: 2016-09-05-PromiseKit-4.0-Released
|
||||
@ -1,236 +0,0 @@
|
||||

|
||||
|
||||
![badge-pod] ![badge-languages] ![badge-pms] ![badge-platforms] ![badge-mit]
|
||||
|
||||
[English](README.markdown)
|
||||
|
||||
---
|
||||
|
||||
現今的程式開發大量使用非同步存取, 難道不正是時候該開始考慮使用合適的工具讓非同步程式更加的強大, 易用, 並且使用愉快?
|
||||
|
||||
```swift
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
||||
|
||||
firstly {
|
||||
when(URLSession.dataTask(with: url).asImage(), CLLocationManager.promise())
|
||||
}.then { image, location -> Void in
|
||||
self.imageView.image = image;
|
||||
self.label.text = "\(location)"
|
||||
}.always {
|
||||
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
||||
}.catch { error in
|
||||
UIAlertView(/*…*/).show()
|
||||
}
|
||||
```
|
||||
PromiseKit 是一個使用 Swift 語言完整實作 Promise 概念的工具套件. 除了能夠完美的和現有的 Objective-C 程式進行整合之外, 也支援多個不同平台, 如, iOS, macOS, tvOs 以及 watchOS.
|
||||
|
||||
# 快速入門
|
||||
|
||||
我們推薦使用 [CocoaPods] 或 [Carthage] 等套件管理程式來進行安裝. 如不使用套件管理程式安裝, 也可以手動下載相關程式, 並把 `PromiseKit.xcodeproj` 拖曳加入您的專案中, 並將 `PromiseKit.framework` 加入.
|
||||
|
||||
## Xcode 8 / Swift 3
|
||||
|
||||
```ruby
|
||||
# CocoaPods >= 1.1.0-rc.2
|
||||
swift_version = "3.0"
|
||||
pod "PromiseKit", "~> 4.0"
|
||||
|
||||
# Carthage
|
||||
github "mxcl/PromiseKit" ~> 4.0
|
||||
|
||||
# SwiftPM
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.Package(url: "https://github.com/mxcl/PromiseKit", majorVersion: 4)
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Xcode 8 / Swift 2.3 or Xcode 7
|
||||
|
||||
```ruby
|
||||
# CocoaPods
|
||||
swift_version = "2.3"
|
||||
pod "PromiseKit", "~> 3.5"
|
||||
|
||||
# Carthage
|
||||
github "mxcl/PromiseKit" ~> 3.5
|
||||
```
|
||||
|
||||
# 相關文件
|
||||
|
||||
您可以在 [promisekit.org] 查詢完整的相關文件.
|
||||
|
||||
## 總覽
|
||||
|
||||
使用 `then` 定義非同步的執行任務:
|
||||
|
||||
```swift
|
||||
login().then { json in
|
||||
//…
|
||||
}
|
||||
```
|
||||
|
||||
鏈結使用:
|
||||
|
||||
```swift
|
||||
login().then { json -> Promise<UIImage> in
|
||||
return fetchAvatar(json["username"])
|
||||
}.then { avatarImage in
|
||||
self.imageView.image = avatarImage
|
||||
}
|
||||
```
|
||||
|
||||
串連式的錯誤/例外處理:
|
||||
|
||||
```swift
|
||||
login().then {
|
||||
return fetchAvatar()
|
||||
}.then { avatarImage in
|
||||
//…
|
||||
}.catch { error in
|
||||
UIAlertView(/*…*/).show()
|
||||
}
|
||||
```
|
||||
|
||||
組合應用:
|
||||
|
||||
```swift
|
||||
let username = login().then{ $0["username"] }
|
||||
|
||||
when(username, CLLocationManager.promise()).then { user, location in
|
||||
return fetchAvatar(user, location: location)
|
||||
}.then { image in
|
||||
//…
|
||||
}
|
||||
```
|
||||
|
||||
毫無難度的重構:
|
||||
|
||||
```swift
|
||||
func avatar() -> Promise<UIImage> {
|
||||
let username = login().then{ $0["username"] }
|
||||
|
||||
return when(username, CLLocationManager.promise()).then { user, location in
|
||||
return fetchAvatar(user, location: location)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
您可以輕易地建構一個非同步任務:
|
||||
|
||||
```swift
|
||||
func fetchAvatar(user: String) -> Promise<UIImage> {
|
||||
return Promise { fulfill, reject in
|
||||
MyWebHelper.GET("\(user)/avatar") { data, err in
|
||||
guard let data = data else { return reject(err) }
|
||||
guard let img = UIImage(data: data) else { return reject(MyError.InvalidImage) }
|
||||
guard let img.size.width > 0 else { return reject(MyError.ImageTooSmall) }
|
||||
fulfill(img)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 更多詳細用法
|
||||
|
||||
您可以透過 [promisekit.org] 學習更多完整的用法.
|
||||
|
||||
## PromiseKit vs. Xcode
|
||||
|
||||
PromiseKit 使用 Swift 進行開發, 下表列出 Xcode 以及 Swifit 的相關對應版本:
|
||||
|
||||
| Swift | Xcode | PromiseKit | CI Status | Release Notes |
|
||||
| ----- | ----- | ---------- | ------------ | ----------------- |
|
||||
| 3 | 8 | 4 | ![ci-master] | [2016/09][news-4] |
|
||||
| 2 | 7/8 | 3 | ![ci-swift2] | [2015/10][news-3] |
|
||||
| 1 | 7 | 3 | – | [2015/10][news-3] |
|
||||
| *N/A* | * | 1† | ![ci-legacy] | – |
|
||||
|
||||
† PromiseKit 1 使用純粹的 Objective-C 進行開發,因此可以在任意的 Xcode 版本中使用,若您需要支援 iOS7 或者更低版本時, 只能選擇使用 PromiseKit 1。
|
||||
|
||||
---
|
||||
|
||||
我們同時維護了一些分支來協助您做不同 Swift 版本間的移植:
|
||||
|
||||
| Xcode | Swift | PromiseKit | Branch | CI Status |
|
||||
| ----- | ----- | -----------| --------------------------- | --------- |
|
||||
| 8.0 | 2.3 | 2 | [swift-2.3-minimal-changes] | ![ci-23] |
|
||||
| 7.3 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
||||
| 7.2 | 2.2 | 2 | [swift-2.2-minimal-changes] | ![ci-22] |
|
||||
| 7.1 | 2.1 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
||||
| 7.0 | 2.0 | 2 | [swift-2.0-minimal-changes] | ![ci-20] |
|
||||
|
||||
我們通常**不會**再對上述的分支進行維護, 但如果有任何的 PR 我們也歡迎提交.
|
||||
|
||||
# 相關擴充
|
||||
|
||||
Promises 僅對執行非同步任務非常有用, 因此我們把 Apple 絕大部份的 API 轉換成 Promises. 透過 CocoaPod 導入套件時即預設帶入 UIKit 和 Foundation, 而其他框架需要在您的 `Podfile` 檔案中進行額外的設定, 例如:
|
||||
|
||||
```ruby
|
||||
pod "PromiseKit/MapKit" # MKDirections().promise().then { /*…*/ }
|
||||
pod "PromiseKit/CoreLocation" # CLLocationManager.promise().then { /*…*/ }
|
||||
```
|
||||
我們所有相關的擴充專案可以到 [PromiseKit org ](https://github.com/PromiseKit) 查詢.
|
||||
|
||||
使用 `Cartfile` 進行設定:
|
||||
|
||||
```ruby
|
||||
github "PromiseKit/MapKit" ~> 1.0
|
||||
```
|
||||
|
||||
## 選擇使用網路相關函式庫
|
||||
|
||||
`URLSession` 一般來說很難勝任複雜的網路存取相關任務; 建議使用 [Alamofire] 或者 [OMGHTTPURLRQ]:
|
||||
|
||||
```swift
|
||||
// pod 'PromiseKit/Alamofire'
|
||||
Alamofire.request("http://example.com", withMethod: .GET).responseJSON().then { json in
|
||||
//…
|
||||
}.catch { error in
|
||||
//…
|
||||
}
|
||||
|
||||
// pod 'PromiseKit/OMGHTTPURLRQ'
|
||||
URLSession.GET("http://example.com").asDictionary().then { json in
|
||||
|
||||
}.catch { error in
|
||||
//…
|
||||
}
|
||||
```
|
||||
針對使用 [AFNetworking] 的開發者, 我們推薦使用 [csotiriou/AFNetworking].
|
||||
|
||||
# 有轉換您現有的程式碼到 Promises 的需求嗎?
|
||||
|
||||
[與我聯繫](mailto:mxcl@me.com), 我在 iOS 上使用 Promises 進行開發已經有多年的經驗, 同時也有 10 年以上開發行動裝置 App 的經驗.
|
||||
|
||||
# 支援
|
||||
|
||||
可以在 [Gitter chat channel](https://gitter.im/mxcl/PromiseKit) 詢問相關問題, 或者直接追蹤我們的 [bug tracker](https://github.com/mxcl/PromiseKit/issues/new)
|
||||
|
||||
|
||||
[travis]: https://travis-ci.org/mxcl/PromiseKit
|
||||
[ci-master]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=master
|
||||
[ci-legacy]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=legacy-1.x
|
||||
[ci-swift2]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.x
|
||||
[ci-23]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.3-minimal-changes
|
||||
[ci-22]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.2-minimal-changes
|
||||
[ci-20]: https://travis-ci.org/mxcl/PromiseKit.svg?branch=swift-2.0-minimal-changes
|
||||
[news-2]: http://promisekit.org/news/2015/05/PromiseKit-2.0-Released/
|
||||
[news-3]: https://github.com/mxcl/PromiseKit/blob/master/CHANGELOG.markdown#300-oct-1st-2015
|
||||
[news-4]: http://promisekit.org/news/2016/09/PromiseKit-4.0-Released/
|
||||
[swift-2.3-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.3-minimal-changes
|
||||
[swift-2.2-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.2-minimal-changes
|
||||
[swift-2.0-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes
|
||||
[promisekit.org]: http://promisekit.org/docs/
|
||||
[badge-pod]: https://img.shields.io/cocoapods/v/PromiseKit.svg?label=version
|
||||
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20watchOS%20%7C%20tvOS-lightgrey.svg
|
||||
[badge-languages]: https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg
|
||||
[badge-mit]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[badge-pms]: https://img.shields.io/badge/supports-CocoaPods%20%7C%20Carthage%20%7C%20SwiftPM-green.svg
|
||||
[OMGHTTPURLRQ]: https://github.com/mxcl/OMGHTTPURLRQ
|
||||
[Alamofire]: http://alamofire.org
|
||||
[AFNetworking]: https://github.com/AFNetworking/AFNetworking
|
||||
[csotiriou/AFNetworking]: https://github.com/csotiriou/AFNetworking-PromiseKit
|
||||
[CocoaPods]: http://cocoapods.org
|
||||
[Carthage]: 2016-09-05-PromiseKit-4.0-Released
|
||||
@ -61,36 +61,43 @@ import Foundation
|
||||
}
|
||||
|
||||
/// - See: `Promise.then()`
|
||||
@discardableResult
|
||||
public func then<T>(on q: DispatchQueue = .default, execute body: @escaping (Any?) throws -> T) -> Promise<T> {
|
||||
return asPromise().then(on: q, execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.then()`
|
||||
@discardableResult
|
||||
public func then(on q: DispatchQueue = .default, execute body: @escaping (Any?) throws -> AnyPromise) -> Promise<Any?> {
|
||||
return asPromise().then(on: q, execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.then()`
|
||||
@discardableResult
|
||||
public func then<T>(on q: DispatchQueue = .default, execute body: @escaping (Any?) throws -> Promise<T>) -> Promise<T> {
|
||||
return asPromise().then(on: q, execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.always()`
|
||||
@discardableResult
|
||||
public func always(on q: DispatchQueue = .default, execute body: @escaping () -> Void) -> Promise<Any?> {
|
||||
return asPromise().always(execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.tap()`
|
||||
@discardableResult
|
||||
public func tap(on q: DispatchQueue = .default, execute body: @escaping (Result<Any?>) -> Void) -> Promise<Any?> {
|
||||
return asPromise().tap(execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.recover()`
|
||||
@discardableResult
|
||||
public func recover(on q: DispatchQueue = .default, policy: CatchPolicy = .allErrorsExceptCancellation, execute body: @escaping (Error) throws -> Promise<Any?>) -> Promise<Any?> {
|
||||
return asPromise().recover(on: q, policy: policy, execute: body)
|
||||
}
|
||||
|
||||
/// - See: `Promise.recover()`
|
||||
@discardableResult
|
||||
public func recover(on q: DispatchQueue = .default, policy: CatchPolicy = .allErrorsExceptCancellation, execute body: @escaping (Error) throws -> Any?) -> Promise<Any?> {
|
||||
return asPromise().recover(on: q, policy: policy, execute: body)
|
||||
}
|
||||
|
||||
@ -27,6 +27,21 @@ public enum PMKError: Error {
|
||||
case castError(Any.Type)
|
||||
}
|
||||
|
||||
extension PMKError: LocalizedError {
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .invalidCallingConvention:
|
||||
return "A closure was called with an invalid calling convention, probably (nil, nil)"
|
||||
case .returnedSelf:
|
||||
return "A promise handler returned itself"
|
||||
case .whenConcurrentlyZero, .join:
|
||||
return "Bad input was provided to a PromiseKit function"
|
||||
case .castError(let type):
|
||||
return "Promise chain sequence failed to cast an object to \(type)."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PMKURLError: Error {
|
||||
/**
|
||||
The URLRequest succeeded but a valid UIImage could not be decoded from
|
||||
@ -55,15 +70,15 @@ public enum PMKURLError: Error {
|
||||
case .invalidImageData:
|
||||
return nil
|
||||
case .badResponse(_, _, let rsp):
|
||||
return rsp as! Foundation.HTTPURLResponse
|
||||
return rsp as? Foundation.HTTPURLResponse
|
||||
case .stringEncoding(_, _, let rsp):
|
||||
return rsp as! Foundation.HTTPURLResponse
|
||||
return rsp as? Foundation.HTTPURLResponse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PMKURLError: CustomStringConvertible {
|
||||
public var description: String {
|
||||
extension PMKURLError: LocalizedError {
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case let .badResponse(rq, data, rsp):
|
||||
if let data = data, let str = String(data: data, encoding: .utf8), let rsp = rsp {
|
||||
|
||||
@ -15,6 +15,7 @@ extension Promise {
|
||||
//…
|
||||
}
|
||||
*/
|
||||
@discardableResult
|
||||
public func then(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> AnyPromise) -> Promise<Any?> {
|
||||
return Promise<Any?>(sealant: { resolve in
|
||||
state.then(on: q, else: resolve) { value in
|
||||
|
||||
@ -146,6 +146,7 @@ open class Promise<T> {
|
||||
//…
|
||||
}
|
||||
*/
|
||||
@discardableResult
|
||||
public func then<U>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> U) -> Promise<U> {
|
||||
return Promise<U> { resolve in
|
||||
state.then(on: q, else: resolve) { value in
|
||||
@ -169,6 +170,7 @@ open class Promise<T> {
|
||||
//…
|
||||
}
|
||||
*/
|
||||
@discardableResult
|
||||
public func then<U>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> Promise<U>) -> Promise<U> {
|
||||
var resolve: ((Resolution<U>) -> Void)!
|
||||
let rv = Promise<U>{ resolve = $0 }
|
||||
@ -199,26 +201,31 @@ open class Promise<T> {
|
||||
//…
|
||||
}
|
||||
*/
|
||||
@discardableResult
|
||||
public func then<U, V>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> (Promise<U>, Promise<V>)) -> Promise<(U, V)> {
|
||||
return then(on: q, execute: body) { when(fulfilled: $0.0, $0.1) }
|
||||
}
|
||||
|
||||
/// This variant of `then` allows returning a tuple of promises within provided closure.
|
||||
@discardableResult
|
||||
public func then<U, V, X>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> (Promise<U>, Promise<V>, Promise<X>)) -> Promise<(U, V, X)> {
|
||||
return then(on: q, execute: body) { when(fulfilled: $0.0, $0.1, $0.2) }
|
||||
}
|
||||
|
||||
/// This variant of `then` allows returning a tuple of promises within provided closure.
|
||||
@discardableResult
|
||||
public func then<U, V, X, Y>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> (Promise<U>, Promise<V>, Promise<X>, Promise<Y>)) -> Promise<(U, V, X, Y)> {
|
||||
return then(on: q, execute: body) { when(fulfilled: $0.0, $0.1, $0.2, $0.3) }
|
||||
}
|
||||
|
||||
/// This variant of `then` allows returning a tuple of promises within provided closure.
|
||||
@discardableResult
|
||||
public func then<U, V, X, Y, Z>(on q: DispatchQueue = .default, execute body: @escaping (T) throws -> (Promise<U>, Promise<V>, Promise<X>, Promise<Y>, Promise<Z>)) -> Promise<(U, V, X, Y, Z)> {
|
||||
return then(on: q, execute: body) { when(fulfilled: $0.0, $0.1, $0.2, $0.3, $0.4) }
|
||||
}
|
||||
|
||||
/// utility function to serve `then` implementations with `body` returning tuple of promises
|
||||
@discardableResult
|
||||
private func then<U, V>(on q: DispatchQueue, execute body: @escaping (T) throws -> V, when: @escaping (V) -> Promise<U>) -> Promise<U> {
|
||||
return Promise<U> { resolve in
|
||||
state.then(on: q, else: resolve) { value in
|
||||
@ -266,6 +273,7 @@ open class Promise<T> {
|
||||
- Parameter execute: The handler to execute if this promise is rejected.
|
||||
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
|
||||
*/
|
||||
@discardableResult
|
||||
public func recover(on q: DispatchQueue = .default, policy: CatchPolicy = .allErrorsExceptCancellation, execute body: @escaping (Error) throws -> Promise) -> Promise {
|
||||
var resolve: ((Resolution<T>) -> Void)!
|
||||
let rv = Promise{ resolve = $0 }
|
||||
@ -292,6 +300,7 @@ open class Promise<T> {
|
||||
- Parameter execute: The handler to execute if this promise is rejected.
|
||||
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
|
||||
*/
|
||||
@discardableResult
|
||||
public func recover(on q: DispatchQueue = .default, policy: CatchPolicy = .allErrorsExceptCancellation, execute body: @escaping (Error) throws -> T) -> Promise {
|
||||
return Promise { resolve in
|
||||
state.catch(on: q, policy: policy, else: resolve) { error in
|
||||
|
||||
@ -208,7 +208,7 @@ extension UnsealedState: CustomStringConvertible {
|
||||
rv = "\(resolution)"
|
||||
}
|
||||
}
|
||||
return "UnsealedState: \(rv)"
|
||||
return "UnsealedState: \(rv!)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -177,7 +177,11 @@ public func when<T, PromiseIterator: IteratorProtocol>(fulfilled promiseIterator
|
||||
func testDone() {
|
||||
barrier.sync {
|
||||
if pendingPromises == 0 {
|
||||
#if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))
|
||||
root.fulfill(promises.flatMap{ $0.value })
|
||||
#else
|
||||
root.fulfill(promises.compactMap{ $0.value })
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user