【问题标题】:Run multiple request at a time and continue as soon there is success一次运行多个请求并在成功后继续
【发布时间】:2021-05-07 02:56:38
【问题描述】:

给定一组 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]
        }

【问题讨论】:

    标签: swift rx-swift moya


    【解决方案1】:

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

    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 上发布一些代码或查看示例代码。

    【讨论】:

    • 是的,好吧,因为这对我来说很奇怪,我正在尝试学习 RxSwift,但对在哪里使用什么感到困惑 :) 任何提示或资源,以了解该放在哪里.asObservable()do 而不是 subscribe?
    • 你的代码看起来干净多了!万分感谢!我会检查.mergethingy
    • 99% 的时间使用subscribe。我想在过去的 6 年中,我只使用了do 可能只有 10 次。仅当编译器抱怨类型不匹配并且使用它会使类型匹配时才使用asObservable()。来看看 RxSwift 松弛。你会在那里得到很多帮助。 (rxslack.herokuapp.com)
    • 我将所有内容都放入Single.create,这样我就可以订阅该函数,disposable!.dispose() 尝试使用,所以当使用可访问的 url 时链会停止
    猜你喜欢
    • 2010-10-10
    • 2011-08-12
    • 2022-10-14
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    相关资源
    最近更新 更多