使用 RxMoya 无法在 RxSwift 上获取 Completed 事件
Not getting Completed event on RxSwift with RxMoya
以下代码有效:
let provider = RxMoyaProvider<MyAPI>( stubClosure: MoyaProvider.delayedStub(3))
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=10=]) else {
fatalError("Invalid Student Object")
}
return students
} as [Student]
}
.subscribe(onNext: {
print([=10=])
}, onCompleted: {
print([=10=]) // This one is being called.
})
.disposed(by: rx.disposeBag)
上面的代码中调用了onCompleted方法,下面的代码中没有。
我正在尝试使用 UITableView 中的刷新触发器来刷新内容。我想在开始时加载内容,所以我在 ViewModel
的以下代码中使用 startWith(())
let results: Driver<[Student]>
var refreshTrigger = PublishSubject<Void>()
results = refreshTrigger
.startWith(())
.do(onNext: {
execute.value = true
})
.flatMapLatest {
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
}
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=11=]) else {
fatalError("Invalid Student Object")
}
return students
}
}
.do(onNext: {
items.value = [=11=]
execute.value = false
noResults.value = items.value.isEmpty
}, onCompleted: {
print([=11=])
})
.asDriver(onErrorJustReturn: [])
在控制器中,我在 viewdidload 中调用以下内容。
viewModel
.results
.asObservable()
.map { StudentGroup(header: "Follower", items: [=12=]) }
.subscribe(onNext: {
print([=12=])
}, onCompleted: {
print([=12=]) // This is not being called.
})
.disposed(by: rx.disposeBag)
这里没有调用onCompleted。我不知道为什么?请帮帮我。
flatMapLatest 不会发送 onCompleted 事件,除非它的输入(在您的例子中是 PublishSubject)完成。
Moya 请求可以发送它们自己的 onCompleted 事件,但是当 flatMapLatest 合并结果时,这些事件会被过滤掉。
换句话说,有一个从 PublishSubject 到数据源的长期订阅没有完成,它也不应该完成。 (编辑)
(否则您会在第一次加载后失去刷新功能。)
我从 RxSwift Slack 频道的 Zsolt Varadi 那里得到了帮助。
这是解决方案
results = refreshTrigger
.startWith(())
.do(onNext: {
execute.value = true
})
.flatMapLatest {
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=10=]) else {
fatalError("Invalid Student Object")
}
return students
} as [Student]
}
.map { StudentGroup(header: "Follower", items: [=10=]) }
.toArray()
.catchErrorJustReturn([])
.do(onNext: {
studentGroups.value = [=10=]
execute.value = false
guard let isEmpty = studentGroups.value.first?.items.isEmpty else {
return
}
noResults.value = isEmpty
})
}
.asDriver(onErrorJustReturn: [])
以下代码有效:
let provider = RxMoyaProvider<MyAPI>( stubClosure: MoyaProvider.delayedStub(3))
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=10=]) else {
fatalError("Invalid Student Object")
}
return students
} as [Student]
}
.subscribe(onNext: {
print([=10=])
}, onCompleted: {
print([=10=]) // This one is being called.
})
.disposed(by: rx.disposeBag)
上面的代码中调用了onCompleted方法,下面的代码中没有。
我正在尝试使用 UITableView 中的刷新触发器来刷新内容。我想在开始时加载内容,所以我在 ViewModel
的以下代码中使用startWith(())
let results: Driver<[Student]>
var refreshTrigger = PublishSubject<Void>()
results = refreshTrigger
.startWith(())
.do(onNext: {
execute.value = true
})
.flatMapLatest {
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
}
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=11=]) else {
fatalError("Invalid Student Object")
}
return students
}
}
.do(onNext: {
items.value = [=11=]
execute.value = false
noResults.value = items.value.isEmpty
}, onCompleted: {
print([=11=])
})
.asDriver(onErrorJustReturn: [])
在控制器中,我在 viewdidload 中调用以下内容。
viewModel
.results
.asObservable()
.map { StudentGroup(header: "Follower", items: [=12=]) }
.subscribe(onNext: {
print([=12=])
}, onCompleted: {
print([=12=]) // This is not being called.
})
.disposed(by: rx.disposeBag)
这里没有调用onCompleted。我不知道为什么?请帮帮我。
flatMapLatest 不会发送 onCompleted 事件,除非它的输入(在您的例子中是 PublishSubject)完成。 Moya 请求可以发送它们自己的 onCompleted 事件,但是当 flatMapLatest 合并结果时,这些事件会被过滤掉。 换句话说,有一个从 PublishSubject 到数据源的长期订阅没有完成,它也不应该完成。 (编辑) (否则您会在第一次加载后失去刷新功能。)
我从 RxSwift Slack 频道的 Zsolt Varadi 那里得到了帮助。
这是解决方案
results = refreshTrigger
.startWith(())
.do(onNext: {
execute.value = true
})
.flatMapLatest {
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map { respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else {
throw APIError.wrongJSONParsing
}
return studentsJsonArray.map {
guard let students = Student.fromJSON([=10=]) else {
fatalError("Invalid Student Object")
}
return students
} as [Student]
}
.map { StudentGroup(header: "Follower", items: [=10=]) }
.toArray()
.catchErrorJustReturn([])
.do(onNext: {
studentGroups.value = [=10=]
execute.value = false
guard let isEmpty = studentGroups.value.first?.items.isEmpty else {
return
}
noResults.value = isEmpty
})
}
.asDriver(onErrorJustReturn: [])