web-dev-qa-db-ja.com

迅速。組み合わせる。再試行時にパブリッシャーブロックを複数回呼び出す方法はありますか?

Swift/Combineのretry()を使用してエラーが発生したときに、ネットワークリクエストを複数回実行したい。パブリッシャー内のブロックは1回だけ呼び出されます。つまり、エラーが発生したときに、実際のアプリに対して要求が1つだけ行われます。私のコードは:

_import UIKit
import Combine
import PlaygroundSupport

enum TestFailureCondition: Error {
    case invalidServerResponse
}

var backgroundQueue: DispatchQueue = DispatchQueue(label: "backgroundQueue")

var failPublisher: AnyPublisher<(Data, URLResponse), Error> {
    Future<(Data, URLResponse), Error> { promise in
        print("Attempt to call")
        backgroundQueue.asyncAfter(deadline: .now() + Double.random(in: 1..<3)) {
            promise(.failure(TestFailureCondition.invalidServerResponse))
        }
    }
    .eraseToAnyPublisher()
}

let cancellable = failPublisher
.print("(1)>")
.retry(3)
.print("(2)>")
.sink(receiveCompletion: { fini in
    print(" ** .sink() received the completion:", String(describing: fini))


    PlaygroundPage.current.finishExecution()
}, receiveValue: { stringValue in
    print(" ** .sink() received \(stringValue)")
})

PlaygroundPage.current.needsIndefiniteExecution = true
_

エラーが発生する前に、backgroundQueue.asyncAfter(deadline)が3回呼び出されることを期待しています。なぜ誰か知っていますか?

6
Dmitry

tryCatch()関数を使用して別のリクエストを行うことで、予想どおりの動作を実現することができました: Link

リンクには、上記のDeferred {}を含む、同じ動作を実現する2つの方法が含まれています。

1
Dmitry