This repository was archived by the owner on Dec 27, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Composition
DimaMishchenko edited this page Jul 17, 2018
·
3 revisions
Returns the new Future with the result you return to closure or with error if the first Future contains error.
// with value
let mapFuture = Future<Int>(value: 100)
mapFuture.onSuccess { value in
// value == 100
}
mapFuture.map { value -> String in
return "\(value) now it's string"
}.onComplete { result in
switch result {
case .value(let value):
print(value) // "100 now it's string""
case .error(let error):
print(error) // no error
}
}
// with error
let error = NSError(domain: "", code: -1, userInfo: nil)
let mapErrorFuture = Future<Int>(error: error)
mapErrorFuture.map { value -> String in
return "\(value)"
}.onComplete { result in
switch result {
case .value(let value):
print(value) // no value
case .error(let error):
print(error) // error
}
}Returns the new Future with the Future you return to closure or with error if the first Future contains error.
let flatMapFuture = Future<Int>(value: 1)
flatMapFuture.flatMap { value -> Future<String> in
return Future<String>(value: "\(value * 100)%")
}.onSuccess { value in
print(value) // "100%"
}Error handling is same as map.
Returns the Future if value satisfies the filtering else returns error.
let filterFuture = Future<Int>(value: 500)
// value
filterFuture.filter { value -> Bool in
return value > 100
}.onComplete { result in
switch result {
case .value(let value):
print(value) // 100
case .error(let error):
print(error) // no error
}
}
// error
filterFuture.filter { value -> Bool in
return value > 1000
}.onComplete { result in
switch result {
case .value(let value):
print(value) // no value
case .error(let error):
print(error) // FutureError.filterError
}
}
// with custom error
let myCustomError = NSError(domain: "", code: -1, userInfo: nil)
filterFuture.filter(error: myCustomError) { value -> Bool in
return value > 1000
}.onComplete { result in
switch result {
case .value(let value):
print(value) // no value
case .error(let error):
print(error) // myCustomError
}
}If the Future contains or will contain error you can recover it with the new value.
let recoverFuture = Future<Int>(error: error)
recoverFuture.onComplete { result in
switch result {
case .value(let value):
print(value) // no value
case .error(let error):
print(error) // error
}
}
recoverFuture.recover { error -> Int in
return 100
}.onComplete { result in
switch result {
case .value(let value):
print(value) // 100
case .error(let error):
print(error) // no error
}
}Combines two values into a tuple.
let first = Future<Int>(value: 1)
let second = Future<Int>(value: 2)
first.zip(second).onSuccess { firstValue, secondValue in
print(firstValue) // 1
print(secondValue) // 2
}Returns the new Future with the same value.
let someFuture = Future<String>(value: "and")
someFuture.onSuccess { value in
print(value)
}.andThen { value in
print(value) // "and"
}.andThen { value in
print(value.count) // 3
}If the value of the Future is the another Future you can flatten it.
let future = Future<Future<String>>(value: Future<String>(value: "value"))
future.onSuccess { value in
print(value) // Future<String>(value: "value")
}
future.flatten().onSuccess { value in
print(value) // "value"
}map, flatMap, filter and recover can catch errors and return the Future with this error, so you don't need to handle it with do/catch.
let errorsHandling = Future<String>(value: "")
let errorToThrow = NSError(domain: "", code: -1, userInfo: nil)
errorsHandling.map { value -> String in
throw errorToThrow
}.flatMap { value -> Future<String> in
throw errorToThrow
}.filter { value -> Bool in
throw errorToThrow
}.recover { error -> String in
throw errorToThrow
}