如何在 RxSwift 中延迟地从 Collection 中一个接一个地发出项目
How to emit items, one by one, from Collection with a delay in RxSwift
我想从 anyCollection 创建一个 Observable,它会在延迟后一个一个地发出每个元素。此外,onNext 我想对项目(模型)执行一些更新。
例如:
//喂所有狗,一只一只,间隔5秒
class Dog {
var name: String?
var age: Int?
var feeded = false
init(_ name: String, _ age: Int){
self.name = name
self.age = age
}
}
func feedDogs(){
let dog1 = Dog("Ren", 3)
let dog2 = Dog("Bega", 7)
let dog3 = Dog("Xuxu", 11)
let delay = 6 // seconds
let allDogs = [dog1, dog2, dog3]
// Observable....
// Expected results after subscribe
// Start - > 0 seconds
// dog1.feeded // true
// time lapse -> 6 seconds
// dog2. feeded // true
// timelapse -> 12 seconds
// dog3.feeded // true
}
我尝试像 "zipWith" 一样使用 "zip"(在 RxJava 中),但在 RxSwift 中似乎不受支持。
嗯,我能想到的最简单的方法(虽然可能不是那么优雅)就是这样。
您创建了一个计时器。
let timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(count), userInfo: nil, repeats: true)
和一个计数器
var counter : Int = 0
并在选择器中执行此操作
@objc func count(){
print("i am being here")
rxTimer.value = ()
}
其中 rxTimer 是定义的变量
var rxTimer = Variable<(())>(())
然后你只需调用 observe rxTimer 就这样
rxTimer.asDriver()
.map { (_) -> Int? in
if self.counter == collection.count{
timer.invalidate()
return nil
}
let value = collection[self.counter]
self.counter += 1
return value
}
.filter{[=14=] != nil}
.map{[=14=]!}
其中 collectio 是您定义的集合。这里我定义它是一个int,但是你可以定义任何你想要的。
嗯...经过一些研发,这是针对我的问题的经过测试的工作版本。
Observable.zip(Observable.from(allDogs), Observable<Int>.interval(RxTimeInterval(delay), scheduler: MainScheduler.instance)).subscribe(onNext: { (dog, index) in
print(dog.name)
}
)
我为此写了扩展。
extension Observable {
func with(interval: RxTimeInterval) -> Observable {
return enumerated()
.concatMap { index, element in
Observable
.just(element)
.delay(index == 0 ? RxTimeInterval.seconds(0) : interval,
scheduler: MainScheduler.instance)
}
}
}
样本:
Observable.from([1, 2, 3, 4, 5])
.with(interval: RxTimeInterval.seconds(1))
.subscribe(onNext: {
print([=11=])
})
.disposed(by: disposeBag)
我想从 anyCollection 创建一个 Observable,它会在延迟后一个一个地发出每个元素。此外,onNext 我想对项目(模型)执行一些更新。
例如:
//喂所有狗,一只一只,间隔5秒
class Dog {
var name: String?
var age: Int?
var feeded = false
init(_ name: String, _ age: Int){
self.name = name
self.age = age
}
}
func feedDogs(){
let dog1 = Dog("Ren", 3)
let dog2 = Dog("Bega", 7)
let dog3 = Dog("Xuxu", 11)
let delay = 6 // seconds
let allDogs = [dog1, dog2, dog3]
// Observable....
// Expected results after subscribe
// Start - > 0 seconds
// dog1.feeded // true
// time lapse -> 6 seconds
// dog2. feeded // true
// timelapse -> 12 seconds
// dog3.feeded // true
}
我尝试像 "zipWith" 一样使用 "zip"(在 RxJava 中),但在 RxSwift 中似乎不受支持。
嗯,我能想到的最简单的方法(虽然可能不是那么优雅)就是这样。
您创建了一个计时器。
let timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(count), userInfo: nil, repeats: true)
和一个计数器
var counter : Int = 0
并在选择器中执行此操作
@objc func count(){
print("i am being here")
rxTimer.value = ()
}
其中 rxTimer 是定义的变量
var rxTimer = Variable<(())>(())
然后你只需调用 observe rxTimer 就这样
rxTimer.asDriver()
.map { (_) -> Int? in
if self.counter == collection.count{
timer.invalidate()
return nil
}
let value = collection[self.counter]
self.counter += 1
return value
}
.filter{[=14=] != nil}
.map{[=14=]!}
其中 collectio 是您定义的集合。这里我定义它是一个int,但是你可以定义任何你想要的。
嗯...经过一些研发,这是针对我的问题的经过测试的工作版本。
Observable.zip(Observable.from(allDogs), Observable<Int>.interval(RxTimeInterval(delay), scheduler: MainScheduler.instance)).subscribe(onNext: { (dog, index) in
print(dog.name)
}
)
我为此写了扩展。
extension Observable {
func with(interval: RxTimeInterval) -> Observable {
return enumerated()
.concatMap { index, element in
Observable
.just(element)
.delay(index == 0 ? RxTimeInterval.seconds(0) : interval,
scheduler: MainScheduler.instance)
}
}
}
样本:
Observable.from([1, 2, 3, 4, 5])
.with(interval: RxTimeInterval.seconds(1))
.subscribe(onNext: {
print([=11=])
})
.disposed(by: disposeBag)