一次运行多个请求并在成功后立即继续

问题描述

给定一组 url,有没有办法同时运行它们?但是以这种方式,一旦有一个成功,就会使用该成功的 url 移动到下一个请求。

到目前为止,我尝试链接 concatMap,但以 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()
    }
  }

也尝试过:

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: {
          
          })

也许我使用了 zip,但我如何创建一个 verifyUrl(url) 调用数组? zip 是否完全接受 Observable 数组?

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]
        }

解决方法

如果我正确理解了这个问题,那么您正在寻找这样的东西:

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)
}

但这很难说。您的代码示例有点混乱。将所有代码放在 Single.create 中很奇怪。当您有一次性物品要返回时,从闭包中返回 Disposables.create() 是奇怪的。在 do 块内调用 dispose() 是奇怪的。这么多奇怪的东西...我建议你在 https://codereview.stackexchange.com 上发布一些代码或查看示例代码。