Closed hpbl closed 6 years ago
Hi Hilton,
I guess the docs meant recover
. Do you need something else? Just provide a usage example and we're happy to consider adding a new convenience extension if needed.
Hey @shoumikhin thanks for the quick response, but I don't think recover
does what I need. My use case would be the following:
makeRequest()
.then { // process data and carry on }
.catch { error in
// Retry the request n times before accepting error
}
I'd like to be able to easily retry the request n times before accepting that it failed and carrying on with the error handling.
It would be great to have such extension like in Rx world. If a promise fails, it tries to restart it as many times as you put in parameters.
Thanks to out-of-the-box await
! I'm using it for recursive promise.
// e.g: each page page 10 items & total of 7 pages
func getItemsCountAt(page: Int) -> Promise<Int> {
let items = page > 7 ? 0 : 10
return Promise(items)
}
// this function keep scanning until page with no more items
func getAllItemsCount() -> Promise<Int> {
return Promise<Int>(on: .global()) { () -> Int in
var page = 1
var totalItems = 0
var pageItems = 0
repeat {
pageItems = try await(getItemsCountAt(page: page))
totalItems += pageItems
page += 1
} while pageItems > 0
return totalItems
}
}
// usage
getAllItemsCount().then { print($0) }
Hi Hilton, sorry for the late reply. We have a prototype of retry
operator working and will ship it soon. Meanwhile, would appreciate your feedback on the following example of possible use-cases:
func fetch(_ url: URL) -> Promise<(Data?, URLResponse?)> {
return wrap { URLSession.shared.dataTask(with: url, completionHandler: $0).resume() }
}
// 1 extra retry attempt on initial fail and 1 second delay before the attempt by default.
retry { fetch(url) }.then { print($0) }.catch { print($0) }
// Custom number of retry attempts, custom delay and a predicate to bail early.
retry(
attempts: 10,
delay: 5,
condition: { error, attemptNumber in
(error as NSError).code == URLError.notConnectedToInternet.rawValue
}
) {
fetch(url)
}.then { value in
print(value)
}.catch { error in
print(error)
}
Let us know if that looks good enough, or if you have any ideas on how to make it even better.
@shoumikhin It looks great for me! The default values are awesome for when you don't need that much control over the retry. Can't wait to use it!
It would be better to have it like this: myAsyncFunc(param) .retry(3) .then { value in
}.catch { error in
}
Hi Anton, I'm afraid that won't be possible, because in our implementation a promise doesn't hold any work block associated with it, so it's not possible to execute it again retrospectively. We've intentionally designed promises that way to avoid extra retain cycles, so that the work block is owned solely by GCD most of the time, instead of a promise itself.
retry
operator is now available in the latest release (1.2.3): https://github.com/google/promises/blob/master/g3doc/index.md#retry
Please let us know if you have any questions or feedback or run into any issues. Thank you!
On the readme is says that using promises makes it easier to retry asynchronous operations. I couldn't find a retry method or anything of the sort, so what would be the simplest way to retry an operation using promises?
Thanks.