Creating Promises
There are several ways to create a Promise
in Then
, from wrapping custom asynchronous operations to creating promises that are already resolved or rejected.
The Standard Initializer
The most common way to create a promise is by wrapping an asynchronous operation. The initializer provides resolve
and reject
closures for you to call when the operation completes.
import Then
enum NetworkError: Error {
case invalidURL
}
func fetchData(from url: URL) -> Promise<Data> {
return Promise { resolve, reject in
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
reject(error) // Operation failed
return
}
if let data = data {
resolve(data) // Operation succeeded
} else {
reject(NetworkError.invalidURL) // Custom failure case
}
}.resume()
}
}
For operations that can report progress, a third progress
closure is available. See Handling Progress for more details.
Promises with Void
For asynchronous operations that do not produce a value upon success (e.g., saving data), you can use Promise<Void>
or the EmptyPromise
typealias. The resolve
closure takes no arguments.
func saveData(_ data: Data) -> Promise<Void> { // or EmptyPromise
return Promise { resolve, reject in
// Perform save operation...
let success = true // a boolean indicating success
if success {
resolve(()) // or just resolve()
} else {
reject(SomeError.saveFailed)
}
}
}
Pre-resolved Promises
Sometimes you need to create a promise that is already in a completed state. This is useful for starting a promise chain with an existing value or for stubbing in tests.
Promise.resolve(value)
Creates a new promise that is already fulfilled with the given value.
let userPromise = Promise.resolve(User(name: "Alice"))
userPromise.then { user in
print(user.name) // Prints "Alice" immediately
}
For Void
promises, you can use Promise.resolve()
with no arguments.
Promise.reject(error)
Creates a new promise that is already rejected with the given error.
let failedPromise = Promise<User>.reject(APIError.userNotFound)
failedPromise.onError { error in
print(error) // Prints "userNotFound"
}
Convenience Initializers
Then
also provides simple initializers for creating pre-resolved promises.
let p1 = Promise(123) // Same as Promise.resolve(123)
let p2 = Promise<Int>(error: MyError.defaultError) // Same as Promise.reject(MyError.defaultError)