如何从Collection中逐个发出项目,并在RxSwift中延迟

时间:2017-11-24 04:12:20

标签: swift rx-swift

我想从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
}

我尝试使用" zip"喜欢" zipWith" (在RxJava中),但似乎不支持RxSwift。

3 个答案:

答案 0 :(得分:2)

嗯......在一些R& D之后,这是我的问题的测试工作版本。

Observable.zip(Observable.from(allDogs), Observable<Int>.interval(RxTimeInterval(delay), scheduler: MainScheduler.instance)).subscribe(onNext: { (dog, index) in
            print(dog.name)
        }
    )

答案 1 :(得分:0)

我为此写了扩展名。

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($0)
    })
    .disposed(by: disposeBag)

答案 2 :(得分:-2)

嗯,我能想到的最简单的方法(虽然可能不那么优雅)就是这样。

您创建一个计时器。

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<(())>(())

然后你只需将观察结果称为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{$0 != nil}
        .map{$0!}

其中collectio是您定义的集合。在这里,我将其定义为int,但您可以将其定义为您想要的任何内容。