Chain requests 和 return 都是 RxSwift 的结果
Chain requests and return both results with RxSwift
我有一个 ContentService
请求一篇文章。该文章回复包含 authorId
属性。
我有一个 ProfileService
允许我通过 userId
.
请求用户配置文件
我正在尝试从 ContentService
请求一篇文章,一旦使用 authorId
属性 完成到 ProfileService
的请求链,我就会喜欢 return 包含文章和个人资料信息的 ContentArticleViewModel
。
我的 ArticleInteractor
看起来像这样 -
final class ArticleInteractor: ArticleInteractorInputProtocol {
let fetchArticleTrigger = PublishSubject<String>()
private lazy var disposeBag = DisposeBag()
weak var output: ArticleInteractorOutputProtocol? {
didSet {
configureSubscriptions()
}
}
private func configureSubscriptions() {
guard let output = output else { return }
fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)
dependencies.contentSvc.fetchContentByIdResponse
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}
}
很简单 fetchArticleTrigger
开始请求,然后我 bind
在 dependencies.contentSvc.fetchContentByIdResponse
上接收响应。
我ContentService
上的方法是-
// MARK:- FetchContentById
// @params: id - String
// return: PublishSubject<ContentArticle>
fetchContentByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getContentById(id: [=12=])) }
.map { (resp: Result<ContentArticle>) in
guard case .success(let props) = resp else { return ContentArticle() }
return props
}
.bind(to: fetchContentByIdResponse)
.disposed(by: disposeBag)
我的 ProfileService
-
上有一个非常相似的设置
// MARK:- FetchUserProfileById
// @params: id - String
// return: PublishSubject<User>
fetchUserProfileByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getProfileByUserId(id: [=13=])) }
.map { (resp: Result<User>) in
guard case .success(let props) = resp else { return User() }
return props
}
.bind(to: fetchUserProfileByIdResponse)
.disposed(by: disposeBag)
我想我会为文章创建一个模型,比如 -
struct ContentArticleViewModel {
var post: ContentArticle
var user: User
}
我在我的 ArticleInteractor
-
中想象类似这个伪代码的东西
dependencies.contentSvc.fetchContentByIdResponse
.flatMapLatest { article in
/* fetch profile using `article.authorId */
}.map { article, profile in
return ContentArticleViewModel(post: article, user: profile)
}
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
但我完全不知道如何最好地处理这个问题。我看过很多关于链接请求的文章,但我很难成功地应用任何东西。
编辑
我目前有一些工作 -
private func configureSubscriptions() {
guard let output = output else { return }
fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)
dependencies.contentSvc.fetchContentByIdResponse
.do(onNext: { [unowned self] article in self.dependencies.profileSvc.fetchUserProfileByIdTrigger.onNext(article.creator.userId)})
.bind(to: fetchArticleResponse)
.disposed(by: disposeBag)
let resp = Observable.combineLatest(fetchArticleResponse, dependencies.profileSvc.fetchUserProfileByIdResponse)
resp
.map { [unowned self] in self.enrichArticleAuthorProps(article: [=16=], user: ) }
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}
private func enrichArticleAuthorProps(article: ContentArticle, user: User) -> ContentArticle {
var updatedArticle = article
updatedArticle.creator = user
return updatedArticle
}
不过我不确定这是否正确。
我不知道为什么这么小的工作你有这么多代码。下面是一个示例,它执行您描述的操作(下载文章、下载作者简介并发出两者),代码少得多,甚至 比我通常使用的代码更多。
protocol ContentService {
func requestArticle(id: String) -> Observable<Article>
func requestProfile(id: String) -> Observable<User>
}
class Example {
let service: ContentService
init(service: ContentService) {
self.service = service
}
func bind(trigger: Observable<String>) -> Observable<(Article, User)> {
let service = self.service
return trigger
.flatMapLatest { service.requestArticle(id: [=10=]) }
.flatMapLatest {
Observable.combineLatest(Observable.just([=10=]), service.requestProfile(id: [=10=].authorId))
}
}
}
或者您可能希望在等待作者个人资料下载时显示文章。在那种情况下是这样的:
func bind(trigger: Observable<String>) -> (article: Observable<Article>, author: Observable<User>) {
let service = self.service
let article = trigger
.flatMapLatest { service.requestArticle(id: [=11=]) }
.share(replay: 1)
let author = article
.flatMapLatest {
service.requestProfile(id: [=11=].authorId)
}
return (article, author)
}
我有一个 ContentService
请求一篇文章。该文章回复包含 authorId
属性。
我有一个 ProfileService
允许我通过 userId
.
我正在尝试从 ContentService
请求一篇文章,一旦使用 authorId
属性 完成到 ProfileService
的请求链,我就会喜欢 return 包含文章和个人资料信息的 ContentArticleViewModel
。
我的 ArticleInteractor
看起来像这样 -
final class ArticleInteractor: ArticleInteractorInputProtocol {
let fetchArticleTrigger = PublishSubject<String>()
private lazy var disposeBag = DisposeBag()
weak var output: ArticleInteractorOutputProtocol? {
didSet {
configureSubscriptions()
}
}
private func configureSubscriptions() {
guard let output = output else { return }
fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)
dependencies.contentSvc.fetchContentByIdResponse
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}
}
很简单 fetchArticleTrigger
开始请求,然后我 bind
在 dependencies.contentSvc.fetchContentByIdResponse
上接收响应。
我ContentService
上的方法是-
// MARK:- FetchContentById
// @params: id - String
// return: PublishSubject<ContentArticle>
fetchContentByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getContentById(id: [=12=])) }
.map { (resp: Result<ContentArticle>) in
guard case .success(let props) = resp else { return ContentArticle() }
return props
}
.bind(to: fetchContentByIdResponse)
.disposed(by: disposeBag)
我的 ProfileService
-
// MARK:- FetchUserProfileById
// @params: id - String
// return: PublishSubject<User>
fetchUserProfileByIdTrigger
.flatMapLatest { [unowned self] in self.client.request(.getProfileByUserId(id: [=13=])) }
.map { (resp: Result<User>) in
guard case .success(let props) = resp else { return User() }
return props
}
.bind(to: fetchUserProfileByIdResponse)
.disposed(by: disposeBag)
我想我会为文章创建一个模型,比如 -
struct ContentArticleViewModel {
var post: ContentArticle
var user: User
}
我在我的 ArticleInteractor
-
dependencies.contentSvc.fetchContentByIdResponse
.flatMapLatest { article in
/* fetch profile using `article.authorId */
}.map { article, profile in
return ContentArticleViewModel(post: article, user: profile)
}
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
但我完全不知道如何最好地处理这个问题。我看过很多关于链接请求的文章,但我很难成功地应用任何东西。
编辑
我目前有一些工作 -
private func configureSubscriptions() {
guard let output = output else { return }
fetchArticleTrigger
.bind(to: dependencies.contentSvc.fetchContentByIdTrigger)
.disposed(by: disposeBag)
dependencies.contentSvc.fetchContentByIdResponse
.do(onNext: { [unowned self] article in self.dependencies.profileSvc.fetchUserProfileByIdTrigger.onNext(article.creator.userId)})
.bind(to: fetchArticleResponse)
.disposed(by: disposeBag)
let resp = Observable.combineLatest(fetchArticleResponse, dependencies.profileSvc.fetchUserProfileByIdResponse)
resp
.map { [unowned self] in self.enrichArticleAuthorProps(article: [=16=], user: ) }
.bind(to: output.fetchArticleResponse)
.disposed(by: disposeBag)
}
private func enrichArticleAuthorProps(article: ContentArticle, user: User) -> ContentArticle {
var updatedArticle = article
updatedArticle.creator = user
return updatedArticle
}
不过我不确定这是否正确。
我不知道为什么这么小的工作你有这么多代码。下面是一个示例,它执行您描述的操作(下载文章、下载作者简介并发出两者),代码少得多,甚至 比我通常使用的代码更多。
protocol ContentService {
func requestArticle(id: String) -> Observable<Article>
func requestProfile(id: String) -> Observable<User>
}
class Example {
let service: ContentService
init(service: ContentService) {
self.service = service
}
func bind(trigger: Observable<String>) -> Observable<(Article, User)> {
let service = self.service
return trigger
.flatMapLatest { service.requestArticle(id: [=10=]) }
.flatMapLatest {
Observable.combineLatest(Observable.just([=10=]), service.requestProfile(id: [=10=].authorId))
}
}
}
或者您可能希望在等待作者个人资料下载时显示文章。在那种情况下是这样的:
func bind(trigger: Observable<String>) -> (article: Observable<Article>, author: Observable<User>) {
let service = self.service
let article = trigger
.flatMapLatest { service.requestArticle(id: [=11=]) }
.share(replay: 1)
let author = article
.flatMapLatest {
service.requestProfile(id: [=11=].authorId)
}
return (article, author)
}