Given an array of urls, is there a way to run those at once simultaneously? But in such a way so as soon as there is one success move to the next request using that successful url.
So far I tried chaining concatMap
, and failed with zip
.
func updateAccountInfo() -> Single<Bool> {
var disposable: Disposable? = nil
return Single<Bool>.create { observer in
do {
var urls = try self.settings.domains.value()
disposable = Observable.from(urls)
.enumerated()
.concatMap { index, url -> Single<URL> in
return self.verifyUrl(url)
}
.concatMap { url -> Single<Account> in
return self.apiManager.loadAccountInfo(from: url)
}
.observeOn(MainScheduler.instance)
.do(onNext: { (account: AccountInfo) in
// use account unfo here
disposable!.dispose()
})
.subscribe()
} catch {
observer(.error(error))
}
return Disposables.create()
}
}
Tried like so too:
disposable = Observable.from(urls)
.enumerated()
.concatMap { index, url -> Single<(Bool, URL)> in
return self.verifyUrl(url)
}
.subscribe(onNext: { reachable, url in
if reachable {
self.apiManager.loadAccountInfo(from: url)
.subscribe(onSuccess: { accountInfo in
// use account info here
}, onError: { error in
})
.disposed(by: self.bag)
disposable!.dispose()
} else {
}
}, onError: { error in
}, onCompleted: {
})
Maybe I use zip but how would I create an array of verifyUrl(url)
calls? Does zip
accept arrays of Observable
at all?
let obs = Observable.from(urls)
.enumerated()
.concatMap { index, url -> Single<URL> in
return self.verifyUrl(url)
}
let test = Observable
.zip(obs).map { [urls] in
return [urls]
}
If I understand the question correctly, you are looking for something like this:
func example() throws {
let urls = try self.settings.domains.value()
Observable.merge(urls.map { verifyUrl($0).asObservable() })
.flatMap { [apiManager] url in
apiManager!.loadAccountInfo(from: url)
}
.observe(on: MainScheduler.instance)
.subscribe(onNext: { account in
// use account unfo here
})
.disposed(by: self.disposeBag)
}
But it's hard to tell. Your code samples are a bit jumbled. Putting all your code in a Single.create is odd. Returning a Disposables.create() from the closure when you have a disposable to return is odd. Calling dispose() on a disposable inside the do block is odd. So much weirdness... I suggest you post some code on https://codereview.stackexchange.com or look at sample code.