当前位置:  开发笔记 > 后端 > 正文

RxSwift:防止多个网络请求

如何解决《RxSwift:防止多个网络请求》经验,为你挑选了1个好方法。

我目前遇到使用RxSwift Observables时执行多个网络请求的问题.我知道如果一个人创建了一个冷可观察对象并且它有多个观察者,那么observable将在每次订阅时执行它的块.

我已经尝试创建一个执行网络请求的共享订阅observable,并且会通知多个订阅者结果.以下是我的尝试.

事件顺序

    使用uibutton的tap事件创建视图模型

    在视图模型上将serviceStatus Observable创建为公共属性.此Observable从buttonTapped Observable映射.然后它过滤掉"正在加载"状态.返回的Observable在其上执行了shareReplay(1)以返回共享订阅.

    在视图模型上将serviceExecuting Observable创建为公共属性.此observable是从serviceStatus Observable映射的.如果状态为"正在加载",它将返回true

    将uilabel绑定到serviceStatus Observable

    将活动指示符绑定到serviceExecuting Observable.

当点击按钮时,服务请求被执行三次,我希望它只执行一次.有什么突出的不正确吗?

class ViewController {

    let disposeBag = DisposeBag()
    var button: UIButton!
    var resultLabel: UILabel!
    var activityIndicator: UIActivityIndicator!

    lazy var viewModel = { // 1
        return ViewModel(buttonTapped: self.button.rx.tap.asObservable())
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.viewModel.serviceStatus.bindTo(self.resultLabel.rx_text).addDispsoableTo(disposeBag) // 4
        self.viewModel.serviceExecuting.bindTo(self.activityIndicator.rx_animating).addDispsoableTo(disposeBag) // 5
    }
}

class ViewModel {

    public var serviceStatus: Observable { // 2
        let serviceStatusObseravble = self.getServiceStatusObservable()
        let filtered = serviceStatusObseravble.filter { status in
            return status != "Loading"
        }
        return filtered
    }

    public var serviceExecuting: Observable { // 3
        return self.serviceStatus.map { status in
            return status == "Loading"
        }
        .startWith(false)
    }

    private let buttonTapped: Observable

    init(buttonTapped: Observable) {
        self.buttonTapped = buttonTapped
    }

    private func getServiceStatusObservable() -> Observable {
        return self.buttonTapped.flatMap { _ -> Observable in
            return self.createServiceStatusObservable()
        }
    }

    private func createServiceStatusObservable() -> Observable {
        return Observable.create({ (observer) -> Disposable in

        someAsyncServiceRequest() { result }
            observer.onNext(result)
        })

        return NopDisposable.instance
    })
    .startWith("Loading")
    .shareReplay(1)
}

编辑:

基于下面的对话,以下是我正在寻找的......

我需要对从getServiceStatusObservable()方法返回的Observable应用share()函数,而不是从createServiceStatusObservable()方法返回的Observable.有多个观察者被添加到这个观察者以检查当前状态.这意味着执行网络请求的可观察对象被执行了N次(N是观察者的数量).现在每次点击按钮,网络请求都会执行一次,这就是我需要的.

private func getServiceStatusObservable() -> Observable {
    return self.buttonTapped.flatMap { _ -> Observable in
        return self.createServiceStatusObservable()
    }.share()
}

tomahh.. 5

.shareReplay(1)将仅适用于一个可观察的实例.在createServiceStatusObservable()共享行为中创建它时,只会影响此函数返回的一个值.

class ViewModel {
  let serviceStatusObservable: Observable

  init(buttonTapped: Observable) {
    self.buttonTapped = buttonTapped
    self.serviceStatusObservable = Observable.create({ (observer) -> Disposable in
        someAsyncServiceRequest() { result in
            observer.onNext(result)
        }

        return NopDisposable.instance
    })
    .startWith("Loading")
    .shareReplay(1)
  }

  private func getServiceStatusObservable() -> Observable {
    return self.buttonTapped.flatMap { [weak self] _ -> Observable in
      return self.serviceStatusObservable
    }
  }
}

对于这个版本,serviceStatusObservable只创建一次,因此它的副作用将在每次使用时共享,因为它是相同的实例.



1> tomahh..:

.shareReplay(1)将仅适用于一个可观察的实例.在createServiceStatusObservable()共享行为中创建它时,只会影响此函数返回的一个值.

class ViewModel {
  let serviceStatusObservable: Observable

  init(buttonTapped: Observable) {
    self.buttonTapped = buttonTapped
    self.serviceStatusObservable = Observable.create({ (observer) -> Disposable in
        someAsyncServiceRequest() { result in
            observer.onNext(result)
        }

        return NopDisposable.instance
    })
    .startWith("Loading")
    .shareReplay(1)
  }

  private func getServiceStatusObservable() -> Observable {
    return self.buttonTapped.flatMap { [weak self] _ -> Observable in
      return self.serviceStatusObservable
    }
  }
}

对于这个版本,serviceStatusObservable只创建一次,因此它的副作用将在每次使用时共享,因为它是相同的实例.


是.`share()`只适用于`.share()`调用之上的东西.所以在`getServiceStatusObservable()`中,调用`flatMap`得到的observable将不会被共享.但``serviceStatusObservable`,从`flatMap`返回.
推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有