2

似乎 rx-swift 还没有实现DefaultIfEmpty。还有另一种方法可以模仿这种行为吗?

let myList:[Int] = []
myList.toObservable()
    .switchIfEmpty { () in // <- Not (yet?) implemented
        return Observable.of(1)
    }.subscribeNext { num in
        print(num)
    }

// prints 1
4

3 回答 3

3

我有类似的问题,但只需要来自可观察的 1 个值,所以简单的解决方案是连接,而不是取 1:

yourSingleObservable.concat(Observable.just(defaultValue)).take(1)
于 2016-10-29T14:18:14.630 回答
0

我曾经toArray模仿过这种行为。一个例子PublishSubject(可以很容易地转换为 use myList,我希望):

  let subjectInt = PublishSubject<Int>()
  let emptyReplacement = subjectInt
    .toArray()
    .filter {$0.isEmpty}
    .map{ _ in return 42}

  let defaultIfEmpty = [subjectInt, emptyReplacement].toObservable().merge()

  defaultIfEmpty.subscribeNext {
    print("defaultIfEmpty: \($0)")
  }

  subjectInt.on(.Next(11)) // 
  subjectInt.on(.Next(33)) //comment these 2 lines out to see the default value 42 printed
  subjectInt.on(.Completed)
于 2016-02-25T21:58:21.400 回答
0

为了完善 Michal 所说的,toArray()提供了一个解决方案:

extension Observable {
    func defaultIfEmpty(_ other: Observable<E>) -> Observable<E> {
        let replacement = toArray()
            .flatMap { array -> Observable<E> in
                if array.isEmpty {
                    return other
                } else {
                    return Observable.empty()
                }
            }

        return concat(replacement)
    }
}

用法:

let a = Observable.of(1, 2, 3)
let b = Observable.of(-1, -2, -3)
let c = Observable<Int>.of()

_ = a.defaultIfEmpty(b).subscribe(onNext: { print($0) })

// 1
// 2
// 3

_ = c.defaultIfEmpty(b).subscribe(onNext: { print($0) })

// -1
// -2
// -3
于 2017-02-11T05:59:56.110 回答