此代码使用 RxSwift
import RxSwift
struct Input {
let loadTrigger: Observable<Void>
}
protocol UseCase {
func getEventsLists() -> Observable<[EventsList]>
func saveEventsList(eventsList: EventsList) -> Observable<Void>
}
struct Event {
let creationDate: Date
}
struct EventsList {
let events: [Event]
}
var tempEventsList: EventsList? = nil
func example(useCase: UseCase, input: Input, disposeBag: DisposeBag) {
let events = input.loadTrigger
.flatMapLatest {
useCase.getEventsLists()
.map { $0.first }
.do(onNext: { eventsList in
if eventsList == nil {
let eventsList = EventsList(events: [])
useCase.saveEventsList(eventsList: eventsList)
.subscribe(onNext: {
tempEventsList = eventsList
})
.disposed(by: disposeBag)
} else {
tempEventsList = eventsList
}
})
.map { $0?.events ?? [] }
.asDriverOnErrorJustComplete()
}
}
在我的 iOS 应用程序中,我可以创建事件来显示到既定日期还剩多少。每个事件都有其创建日期。 事件按最后创建的排序(我可以手动更改顺序),因此小部件也显示最后创建的事件(我可以更改事件以手动显示)。
我希望事件列表按时间顺序自动排序,从最新到最旧。
这个问题有简单的答案,但也有一些建议……使用 RxSwift 的一个好处是能够摆脱“厄运金字塔”。这是当你在嵌套闭包中有嵌套闭包时。
您没有利用这一点,因此为了完成工作而缩进了多达 8 个深度。这不是必需的,并且会降低可读性。让我们在回答问题时将这段代码分解成单独的作业:
首先,让我们设置一个
Observable<[EventsList]>
变量,它会在每次 loadTrigger 触发时发出一个新的事件列表数组。请注意,我们正在共享此值,因为它稍后将被多个流使用:
let eventsLists = input.loadTrigger
.flatMapLatest { useCase.getEventsLists() }
.share()
接下来,我们准确定义何时调用
saveEventsList(eventsLists:)
。唯一需要它的时候是 getEventsLists() 返回空数组时。据推测,这将确保下次调用时,getEventsLists() 将至少返回一个列表:
eventsLists
.filter { $0.isEmpty }
.map { _ in }
.subscribe(onNext: {
_ = useCase.saveEventsList(eventsList: EventsList(events: []))
.subscribe()
})
.disposed(by: disposeBag)
现在,让我们准确地定义
tempEventsList
被分配给:
eventsLists
.map { $0.first ?? EventsList(events: []) }
.subscribe(onNext: { eventsList in
tempEventsList = eventsList
})
.disposed(by: disposeBag)
最后,我们得到实际的 Observable 事件数组。如您所见,排序很简单:
let events = eventsLists
.map { $0.first?.events.sorted(by: { $0.creationDate > $1.creationDate }) ?? [] }
所有的代码看起来像这样。每个代码块都是一个单独且定义明确的功能:
let eventsLists = input.loadTrigger
.flatMapLatest { useCase.getEventsLists() }
.share()
eventsLists
.filter { $0.isEmpty }
.map { _ in }
.subscribe(onNext: {
_ = useCase.saveEventsList(eventsList: EventsList(events: []))
.subscribe()
})
.disposed(by: disposeBag)
eventsLists
.map { $0.first ?? EventsList(events: []) }
.subscribe(onNext: { eventsList in
tempEventsList = eventsList
})
.disposed(by: disposeBag)
let events = eventsLists
.map { $0.first?.events.sorted(by: { $0.creationDate > $1.creationDate }) ?? [] }