[英]RxSwift Subscriber receiving multiple events
考慮下面的代碼。
isFetched
,然后調用fetchPopularMovies()
。fetchPopularMovies()
依次調用 API。 當收到響應時,我們將發送OnNext(true)
事件。問題是,我在第二個按鈕點擊后收到多個事件。 如果我添加 onCompleted(),我什至不會在第二個按鈕點擊時收到事件。 我的期望是每次點擊按鈕都會觸發一個事件。 我在這里想念什么?
class ViewController: UIViewController {
let popularMoviesURL = URL(string: "https://api.themoviedb.org/3/movie/popular?api_key=API_KEY")
var isFetched = BehaviorSubject<Bool?>(value:nil)
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func tapButton(_ sender: Any) {
let observable = isFetched.asObservable()
observable.subscribe(onNext: { observer in
guard let result = observer else { return }
print(result)
print("onNext Recieved")
}, onError: { _ in
print("onError Recieved")
}).disposed(by: disposeBag)
fetchPopularMovies()
}
func fetchPopularMovies() {
let task = URLSession.shared.dataTask(with: popularMoviesURL!) {(data, response, error) in
guard let _ = data else { return }
self.isFetched.onNext(true)
//self.isFetched.onCompleted()
}
task.resume()
}
}
反應式代碼是聲明性的。 這是“設置”代碼。 所以它應該放在評論說“加載視圖后做任何額外的設置”的地方。
您可以做的最簡單的更改來解決您遇到的問題是將訂閱移動到viewDidLoad
方法中,正如 Satish Patel 在他的評論中引用的那樣。
override func viewDidLoad() {
super.viewDidLoad()
isFetched.subscribe(onNext: { observer in
guard let result = observer else { return }
print(result)
print("onNext Recieved")
}, onError: { _ in
print("onError Recieved")
}).disposed(by: disposeBag)
}
@IBAction func tapButton(_ sender: Any) {
fetchPopularMovies()
}
(請注意, Subject
應該始終與let
s never var
s 保持一致。)
如果你使用 RxCocoa,你可以進一步簡化這段代碼:
class ViewController: UIViewController {
let button = UIButton()
let isFetched = BehaviorSubject<Bool?>(value:nil)
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let popularMoviesURL = URL(string: "https://api.themoviedb.org/3/movie/popular?api_key=API_KEY")!
let fetchedData = button.rx.tap
.flatMapLatest {
URLSession.shared.rx.data(request: URLRequest(url: popularMoviesURL))
.catch { error in
print("onError Recieved")
return Observable.empty()
}
}
fetchedData
.map { _ in true }
.bind(to: isFetched)
.disposed(by: disposeBag)
}
}
現在,您的所有代碼都是“設置代碼”,所以它們都在viewDidLoad
中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.