Last active
February 12, 2018 10:27
-
-
Save LuizZak/91dc49309961e09ba28ad403e2a21a14 to your computer and use it in GitHub Desktop.
PromiseKit retrying functions using encapsulated blocks that return promises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Retries the given throwing `block` as a promise `tries` times, | |
/// re-calling `block` another time until exhausting the tries. | |
func retry<T>(tries count: Int, block: () throws -> T) -> Promise<T> { | |
return Promise().thenRetry(tries: count, block: block) | |
} | |
/// Retries the given promise-returning `block` as a promise `tries` times, | |
/// re-calling `block` another time until exhausting the tries. | |
func retry<T>(tries count: Int, block: () -> Promise<T>) -> Promise<T> { | |
return Promise().thenRetry(tries: count, block: block) | |
} | |
extension Promise { | |
/// After succeeding this promise, re-tries the given block `tries` times, re-calling `block` another time | |
/// to try to fetch another promise until exhausting the tries. | |
func thenRetry<U>(tries count: Int, block: (T) throws -> Promise<U>) rethrows -> Promise<U> { | |
return self.then { ret in | |
return try block(ret) | |
}.recover { error -> Promise<U> in | |
if(count > 0) { | |
return try self.thenRetry(tries: count - 1, block: block) | |
} | |
throw error | |
} | |
} | |
/// After succeeding this promise, re-tries the given block `tries` times, re-calling `block` another time | |
/// to try to fetch another value until exhausting the tries. | |
func thenRetry<U>(tries count: Int, block: (T) throws -> U) -> Promise<U> { | |
return self.then { ret in | |
return try block(ret) | |
}.recover { error -> Promise<U> in | |
if(count > 0) { | |
return self.thenRetry(tries: count - 1, block: block) | |
} | |
throw error | |
} | |
} | |
} | |
/* | |
Example: | |
// As the start of a promise chain... | |
retry(tries: 3) { | |
myAsyncTask() | |
}.then { | |
// myAsyncTask succeeded within 3 retries! | |
}.error { error in | |
// myAsyncTask failed... | |
} | |
// As the continuation of a promise... | |
myAsyncTask().thenRetry(tries: 3) { result in | |
myOtherAsyncTask() | |
}.then { | |
// myOtherAsyncTask succeeded within 3 retries! | |
}.error { error in | |
// myAsyncTask or myOtherAsyncTask failed... | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment