Skip to content

Instantly share code, notes, and snippets.

@mike-neko
Last active November 22, 2017 02:36
Show Gist options
  • Save mike-neko/4389caf81df1314ec2ed039a264d7f3a to your computer and use it in GitHub Desktop.
Save mike-neko/4389caf81df1314ec2ed039a264d7f3a to your computer and use it in GitHub Desktop.
/// リトライする`Promise`を作成する
///
/// - Parameters:
/// - maxRepeat: 最大リトライ回数。超えた場合は`RetryError`が`throw`される
/// - args: `task`を実行する時に渡す引数
/// - task: 実行させたい非同期処理を指定する。`Promise`を返さないといけない
/// - preRetry: リトライ前に実行される処理を指定する。`false`を返すとリトライはされない
/// - Returns: `Promise`を返す
/// - Note: `RetryError`の定義が必要
func retry<T, U>(maxRepeat: Int, args: U, task: @escaping (U) -> Promise<T>, preRetry: @escaping (Error) -> Bool) -> Promise<T> {
var count = 0 // リトライ回数計測用
func p() -> Promise<T> {
count += 1
return firstly {
task(args)
}.recover { error -> Promise<T> in
guard preRetry(error) else {
// リトライせずにエラーにする
throw error
}
guard count < maxRepeat else {
// リトライ回数超えたのでエラーにする
throw RetryError(error)
}
return p()
}
}
return p()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment