<commit_before>![Then](https://raw.githubusercontent.com/freshOS/then/master/banner.png)

# then
[![Language: Swift 2 and 3](https://img.shields.io/badge/language-swift2|3-f48041.svg?style=flat)](https://developer.apple.com/swift)
![Platform: iOS 8+](https://img.shields.io/badge/platform-iOS%208%2B-blue.svg?style=flat) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Cocoapods compatible](https://img.shields.io/badge/Cocoapods-compatible-4BC51D.svg?style=flat)](https://cocoapods.org)
[![Build Status](https://www.bitrise.io/app/ea9933b066f6a2c4.svg?token=i7LK0uQC1rVuXhDq1iskYg&branch=master)](https://www.bitrise.io/app/ea9933b066f6a2c4)
[![codebeat badge](https://codebeat.co/badges/768d3017-1e65-47e0-b287-afcb8954a1da)](https://codebeat.co/projects/github-com-s4cha-then)
[![Join the chat at https://gitter.im/s4cha/then](https://badges.gitter.im/s4cha/then.svg)](https://gitter.im/s4cha/then?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![License: MIT](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/freshOS/then/blob/master/LICENSE)
[![Release version](https://img.shields.io/badge/release-2.1-blue.svg)]()

[Reason](#why) - [Example](#example) - [Installation](#installation)

```swift
fetchUserId().then { id in
    print("UserID : \(id)")
}.onError { e in
    print("An error occured : \(e)")
}.finally {
    print("Everything is Done :)")
}
```
Because async code is hard to write, hard to read, hard to reason about.   **A pain to maintain**

## Try it
then is part of [freshOS](http://freshos.org) iOS toolset. Try it in an example App !  <a class="github-button" href="https://github.com/freshOS/StarterProject/archive/master.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download freshOS/StarterProject on GitHub">Download Starter Project</a>

## How
By using a **then** keyword that enables you to write aSync code that *reads like an English sentence*  
Async code is now **concise**, **flexible** and **maintainable** ❤️

## What
- [x] Based on the popular Promise / Future concept
- [x] Strongly Typed
- [x] Pure Swift & Lightweight
- [x] Chainable
- [x] Progress support


## Example
### Before
```swift
fetchUserId({ id in
    fetchUserNameFromId(id, success: { name in
        fetchUserFollowStatusFromName(name, success: { isFollowed in
            // The three calls in a row succeeded YAY!
            reloadList()
        }, failure: { error in
            // Fetching user ID failed
            reloadList()
        })
    }, failure: { error in
        // Fetching user name failed
        reloadList()
    })
}) {  error in
    // Fetching user follow status failed
    reloadList()
}
🙉🙈🙊#callbackHell
```

----

### After

```swift
fetchUserId()
    .then(fetchUserNameFromId)
    .then(fetchUserFollowStatusFromName)
    .then(updateFollowStatus)
    .onError(showErrorPopup)
    .finally(reloadList)
```
## 🎉🎉🎉


## Going further 🤓

```swift
fetchUserId().then { id in
    print("UserID : \(id)")
}.onError { e in
    print("An error occured : \(e)")
}.finally {
    print("Everything is Done :)")
}
```

If we want this to be **maintainable**, it should read *like an English sentence*  
We can do this by extracting our blocks into separate functions:

```swift
fetchUserId()
    .then(printUserID)
    .onError(showErrorPopup)
    .finally(reloadList)
```

This is now **concise**, **flexible**, **maintainable**, and it reads like an English sentence <3  
Mental sanity saved
// #goodbyeCallbackHell


## Writing your own Promise 💪
Wondering what fetchUserId() is?  
It is a simple function that returns a strongly typed promise :

```swift
func fetchUserId() -> Promise<Int> {
    return Promise { resolve, reject in
        print("fetching user Id ...")
        wait { resolve(1234) }
    }
}
```
Here you would typically replace the dummy wait function by your network request <3

## Progress

As for `then` and `onError`, you can also call a `progress` block for things like uploading an avatar for example.

```swift
uploadAvatar().progress { p in
  // Here update progressView for example
}
.then(doSomething)
.onError(showErrorPopup)
.finally(doSomething)
```

## Registering a block for later
Our implementation slightly differs from the original javascript Promises. Indeed, they do not start right away, on purpose. Calling `then`, `onError`, or `finally` will start them automatically.

Calling `then` starts a promise if it is not already started.
In some cases, we only want to register some code for later.
For instance, in the case of JSON to Swift model parsing, we often want to attach parsing blocks to JSON promises, but without starting them.

In order to do that we need to use `registerThen` instead. It's the exact same thing as `then` without starting the promise right away.

```swift
let fetchUsers:Promise<[User]> = fetchUsersJSON().registerThen(parseUsersJSON)

// Here promise is not launched yet \o/

// later...
fetchUsers.then { users in
    // YAY
}
```

## Bonus : whenAll

`whenAll` calls you back when all the promises passed are fullfiled :
```swift
whenAll(fetchUsersA(),fetchUsersB(), fetchUsersC()).then { allUsers in
  // All the promises came back
}
```

## Returning a rejecting promise

Oftetimes we need to return a rejecting promise as such :

```swift
return Promise { _, reject in
  reject(anError)
}
```

This can be written with the following shortcut :
```swift
return Promise.reject(error:anError)
```

## Installation

### Cocoapods
```swift
pod 'thenPromise'
use_frameworks!
```

#### Carthage
```
github "freshOS/then"
```
#### Manually
Simply Copy and Paste `.swift` files in your Xcode Project :)

#### As A Framework
Grab this repository and build the Framework target on the example project. Then Link against this framework.


## Contributors

[S4cha](https://github.com/S4cha), [YannickDot](https://github.com/YannickDot), [Damien](https://github.com/damien-nd),
[piterlouis](https://github.com/piterlouis)
<commit_msg>Updates documentation<commit_after>![Then](https://raw.githubusercontent.com/freshOS/then/master/banner.png)

# then
[![Language: Swift 2 and 3](https://img.shields.io/badge/language-swift2|3-f48041.svg?style=flat)](https://developer.apple.com/swift)
![Platform: iOS 8+](https://img.shields.io/badge/platform-iOS%208%2B-blue.svg?style=flat) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Cocoapods compatible](https://img.shields.io/badge/Cocoapods-compatible-4BC51D.svg?style=flat)](https://cocoapods.org)
[![Build Status](https://www.bitrise.io/app/ea9933b066f6a2c4.svg?token=i7LK0uQC1rVuXhDq1iskYg&branch=master)](https://www.bitrise.io/app/ea9933b066f6a2c4)
[![codebeat badge](https://codebeat.co/badges/768d3017-1e65-47e0-b287-afcb8954a1da)](https://codebeat.co/projects/github-com-s4cha-then)
[![Join the chat at https://gitter.im/s4cha/then](https://badges.gitter.im/s4cha/then.svg)](https://gitter.im/s4cha/then?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![License: MIT](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/freshOS/then/blob/master/LICENSE)
[![Release version](https://img.shields.io/badge/release-2.1-blue.svg)]()

[Reason](#why) - [Example](#example) -  [Documentation](#documentation) - [Installation](#installation)

```swift
fetchUserId().then { id in
    print("UserID : \(id)")
}.onError { e in
    print("An error occured : \(e)")
}.finally {
    print("Everything is Done :)")
}
```
Because async code is hard to write, hard to read, hard to reason about.   **A pain to maintain**

## Try it
then is part of [freshOS](http://freshos.org) iOS toolset. Try it in an example App !  <a class="github-button" href="https://github.com/freshOS/StarterProject/archive/master.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download freshOS/StarterProject on GitHub">Download Starter Project</a>

## How
By using a **then** keyword that enables you to write aSync code that *reads like an English sentence*  
Async code is now **concise**, **flexible** and **maintainable** ❤️

## What
- [x] Based on the popular Promise / Future concept
- [x] Strongly Typed
- [x] Pure Swift & Lightweight
- [x] Chainable
- [x] Progress support
- [x] Common Promise helpers: `race`, `recover` `validate` `retry` `bridgeError` ...


## Example
### Before
```swift
fetchUserId({ id in
    fetchUserNameFromId(id, success: { name in
        fetchUserFollowStatusFromName(name, success: { isFollowed in
            // The three calls in a row succeeded YAY!
            reloadList()
        }, failure: { error in
            // Fetching user ID failed
            reloadList()
        })
    }, failure: { error in
        // Fetching user name failed
        reloadList()
    })
}) {  error in
    // Fetching user follow status failed
    reloadList()
}
🙉🙈🙊#callbackHell
```

----

### After

```swift
fetchUserId()
    .then(fetchUserNameFromId)
    .then(fetchUserFollowStatusFromName)
    .then(updateFollowStatus)
    .onError(showErrorPopup)
    .finally(reloadList)
```
## 🎉🎉🎉


## Going further 🤓

```swift
fetchUserId().then { id in
    print("UserID : \(id)")
}.onError { e in
    print("An error occured : \(e)")
}.finally {
    print("Everything is Done :)")
}
```

If we want this to be **maintainable**, it should read *like an English sentence*  
We can do this by extracting our blocks into separate functions:

```swift
fetchUserId()
    .then(printUserID)
    .onError(showErrorPopup)
    .finally(reloadList)
```

This is now **concise**, **flexible**, **maintainable**, and it reads like an English sentence <3  
Mental sanity saved
// #goodbyeCallbackHell


## Documentation

1. [Writing your own Promise](#writing-your-own-promise-💪)
2. [Progress](#progress)
3. [Registering a block for later](#registering-a-block-for-later)
4. [Returning a rejecting promise](#returning-a-rejecting-promise)
5. [Common Helpers](#common-helpers)
  1. [race](#race)
  2. [recover](#recover)
  3. [validate](#validate)
  4. [retry](#retry)
  5. [bridgeError](#bridgeError)
  6. [whenAll](#whenAll)
6. [Async](#async)


### Writing your own Promise 💪
Wondering what fetchUserId() is?  
It is a simple function that returns a strongly typed promise :

```swift
func fetchUserId() -> Promise<Int> {
    return Promise { resolve, reject in
        print("fetching user Id ...")
        wait { resolve(1234) }
    }
}
```
Here you would typically replace the dummy wait function by your network request <3

### Progress

As for `then` and `onError`, you can also call a `progress` block for things like uploading an avatar for example.

```swift
uploadAvatar().progress { p in
  // Here update progressView for example
}
.then(doSomething)
.onError(showErrorPopup)
.finally(doSomething)
```

### Registering a block for later
Our implementation slightly differs from the original javascript Promises. Indeed, they do not start right away, on purpose. Calling `then`, `onError`, or `finally` will start them automatically.

Calling `then` starts a promise if it is not already started.
In some cases, we only want to register some code for later.
For instance, in the case of JSON to Swift model parsing, we often want to attach parsing blocks to JSON promises, but without starting them.

In order to do that we need to use `registerThen` instead. It's the exact same thing as `then` without starting the promise right away.

```swift
let fetchUsers:Promise<[User]> = fetchUsersJSON().registerThen(parseUsersJSON)

// Here promise is not launched yet \o/

// later...
fetchUsers.then { users in
    // YAY
}
```

### Returning a rejecting promise

Oftetimes we need to return a rejecting promise as such :

```swift
return Promise { _, reject in
  reject(anError)
}
```

This can be written with the following shortcut :
```swift
return Promise.reject(error:anError)
```

### Common Helpers

#### Race

With `race`, you can send multiple tasks and get the result of the first one coming back :
```swift
race(task1, task2, task3).then { work in
  // The first result !
}
```

#### Recover

With `.recover`, you can provide a fallback value for a failed Promise
You can:
  - Recover with a value
  - Recover with a value for a specific Error type
  - Return a value from a block, enabling you to test the type of error and return distinct values.
  - Recover with another Promise with the same Type

```swift
.recover(with: 12)
.recover(MyError.defaultError, with: 12)
.recover { e in
  if e == x { return 32 }
  if e == y { return 143 }
  throw MyError.defaultError
}
.recover(with: Promise<Int>.resolve(56))
```
Note that in the block version you can also throw your own error \o/


#### Validate

With `.validate`, you can break the promise chain with an assertion block.

You can:
  - Insert assertion in Promise chain
  - Insert assertion and return you own Error

For instance checking if a user is allowed to drink alcohol :
```swift
fetchUserAge()
.validate { $0 > 18 }
.then { age in
  // Offer a drink
}

.validate(withError: MyError.defaultError, { $0 > 18 })`
```
A failed validation will retrun a `PromiseError.validationFailed` by default.

#### Retry

With `retry`, you can restart a failed Promise X number of times.
```swift
doSomething()
  .retry(10)
  .then { v in
   // YAY!
  }.onError { e in
    // Failed 10 times in a row
  }
```

#### BridgeError

With `.bridgeError`, you can intercept a low-level Error and return your own high level error.
The classic use-case is when you receive an api error and you bridge it to your own domain error.

You can:
  - Catch all errors and use your own Error type
  - Catch only a specific error

```swift
.bridgeError(to: MyError.defaultError)
.bridgeError(SomeError, to: MyError.defaultError)
```

#### BridgeError

With `.whenAll`, you can combine multiple calls and get all the results when all the promises are fulfilled :

```swift
whenAll(fetchUsersA(),fetchUsersB(), fetchUsersC()).then { allUsers in
  // All the promises came back
}
```

### Async
`AsyncTask` and `Async<T>` typealisases are provided for those of use who think that Async can be clearer than `Promise`.
Feel free to replace `Promise<Void>` by `AsyncTask` and `Promise<T>` by `Async<T>` wherever needed.
This is purely for the eyes :)


## Installation

### Cocoapods
```swift
pod 'thenPromise'
use_frameworks!
```

#### Carthage
```
github "freshOS/then"
```
#### Manually
Simply Copy and Paste `.swift` files in your Xcode Project :)

#### As A Framework
Grab this repository and build the Framework target on the example project. Then Link against this framework.


## Contributors

[S4cha](https://github.com/S4cha), [YannickDot](https://github.com/YannickDot), [Damien](https://github.com/damien-nd),
[piterlouis](https://github.com/piterlouis)

{'fraction_non_alphanumeric': 0.13784812662793028, 'fraction_numerical': 0.012956655312896546, 'mean_word_length': 4.135116598079561, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 44, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6086214', 'n_tokens_mistral': 5090, 'n_tokens_neox': 4763, 'n_words': 1490}