- A:
compactMap
- B:
publish
- C:
flatMap
- D:
withLatestFrom
- A:
do
- B:
share
- C:
repeatElement
- D:
amb
- A:
buffer
- B:
window
- C:
debounce
- D:
throttle
- A:
amb
- B:
buffer
- C:
filter
- D:
map
- A:
amb
- B:
buffer
- C:
filter
- D:
timer
- A:
从一个错误事件中恢复,将错误事件替换成一个备选序列
- B:
拦截一个 error 事件,将它替换成其他的元素或者一组元素
- C:
具备重试的能力
- D:
可以使得 Observable 正常结束,或者根本都不需要结束
- A:
takeUntil
- B:
withLatestFrom
- C:
skipUntil
- D:
skipWhile
- A:
combineLatest
- B:
zip
- C:
merge
- D:
startWith
- A:
ConcatMap可以将所有子 Observables 的元素发送出来
- B:
FlatMap打印Observables的元素是按子Observables先后顺序依次打印的
- C:
FlatMap过程会将每一个元素转换成Observables
- D:
ConcatMap能够立即处理新的子Observables的订阅
- A:
一定在 MainScheduler 订阅
- B:
一定在 MainScheduler 监听
- C:
没有共享附加作用
- D:
不会产生 error 事件
- A:
flatMapLatest是map和switchLatest操作符的组合
- B:
可以用withLatestFrom加distinctUntilChanged实现sample操作符
- C:
amb命令只处理最先接收到的next事件的数据源,其他全部忽略
- D:
在指定时间内没有发任何出元素,timeout操作符会产生一个超时的error事件
- A:
subscribeOn
- B:
obseverOn
- C:
materialize
- D:
using
- A:
Single对象
- B:
publish操作符
- C:
refCount操作符
- D:
buffer操作符
- A:
Single
- B:
Signal
- C:
Driver
- D:
ControlEvent
- A:
PublishRelay
- B:
ControlEvent
- C:
ControlProperty
- D:
BehaviorSubject
- A:
skipWhile
- B:
takeUntil
- C:
sample
- D:
refCount
- A:
refCount
- B:
publish
- C:
sample
- D:
replay
let o = Observable.from([1,2,3]).publish()
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
_ = o.connect()
_ = o.subscribe(onNext: { print($0) })
- A:
1 2 3 1 2 3 1 2 3
- B:
1 2 3 1 2 3
- C:
1 1 2 2 3 3
- D:
1 1 2 2 3 3 1 2 3
let o = Observable.from([1,2,3]).replay(2)
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
_ = o.connect()
_ = o.subscribe(onNext: { print($0) })
_ = o.connect()
- A:
1 1 2 2 3 3 1 2 3
- B:
1 1 2 2 3 3 2 3
- C:
1 1 2 2 3 3 1 1 1 2 2 2 3 3 3
- D:
1 1 2 2 3 3 2 3 1 1 1 2 2 2 3 3 3
let o = Observable.from([1,2,3]).share(replay: 2)
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
- A:
1 2 3 1 2 3 1 2 3
- B:
1 2 3 2 3 2 3
- C:
2 3 2 3 2 3
- D:
1 1 1 2 2 2 3 3 3
let o = Observable.from([1,2,3]).share(replay: 1, scope: .forever)
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
- A:
1 2 3 1 2 3 1 2 3
- B:
1 2 3 3 3
- C:
3 3 3
- D:
1 1 1 2 2 2 3 3 3
let o = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(3)
.share(replay: 2)
_ = o.subscribe(onNext: { print($0) })
_ = o.subscribe(onNext: { print($0) })
- A:
0 1 2 0 1 2 0 1 2
- B:
0 1 2 1 2 1 2
- C:
1 2 1 2 1 2
- D:
0 0 1 1 2 2
let o = Observable.from([1,2]).share(replay: 1, scope: .forever)
let d1 = o.subscribe(onNext: { print($0) })
d1.dispose()
_ = o.subscribe(onNext: { print($0) })
let o = Observable.from([1,2]).concat(Observable.never()).share(replay: 1, scope: .forever)
let d1 = o.subscribe(onNext: { print($0) })
d1.dispose()
_ = o.subscribe(onNext: { print($0) })
- A:
1 2 2 1 2
和1 2 2
- B:
1 2 2 1 2
和1 2 2 1 2
- C:
1 2 2
和1 2 2
- D:
1 2 2
和1 2 2 1 2
let s = PublishSubject<Int>()
let t = s.throttle(.seconds(2), scheduler: MainScheduler.instance)
let d = s.debounce(.seconds(2), scheduler: MainScheduler.instance)
_ = d.subscribe(onNext: { print("b" + String($0)) })
_ = t.subscribe(onNext: { print("a" + String($0)) })
s.onNext(1)
_ = Observable<Never>.empty().delay(.seconds(1), scheduler: MainScheduler.instance).subscribe {
s.onNext(2)
}
- A:
b1 b2 a2
- B:
a1 a2 b2
- C:
a1 b1 a2 b2
- D:
a1 b2 a2
let o = Observable.from(1...10).groupBy { $0 % 3 }.flatMap { $0.toArray() }
_ = o.subscribe(onNext: { print($0) })
- A:
[1, 4, 7, 10]
- B:
[1, 2, 3]
、[4, 5, 6]
和[7, 8, 9]
- C:
[1, 4, 7, 10]
、[2, 5, 8]
和[3, 6, 9]
- D:
[1, 2, 3]
、[4, 5, 6]
、[7, 8, 9]
和[10]
let o = Observable.from(1...10).groupBy { $0 % 3 }.concatMap { $0 }
_ = o.subscribe(onNext: { print($0) })
- A:
1 4 7 10
- B:
1 2 3 4 5 6 7 8 9
- C:
1 4 7 10 2 5 8 3 6 9
- D:
1 2 3 4 5 6 7 8 9 10
let o = Observable.from(1...10).groupBy { $0 % 3 }.flatMap { $0 }
_ = o.subscribe(onNext: { print($0) })
- A:
1 4 7 10
- B:
1 2 3 4 5 6 7 8 9
- C:
1 4 7 10 2 5 8 3 6 9
- D:
1 2 3 4 5 6 7 8 9 10
let o1 = Observable.interval(.seconds(1), scheduler: MainScheduler.instance).map{ String(UnicodeScalar(UInt8($0 + 97))) }.take(3)
let o2 = Observable<Int>.interval(.milliseconds(700), scheduler: MainScheduler.instance).take(4)
_ = Observable.combineLatest(o1, o2) { $0 + String($1) }.subscribe(onNext: { print($0) })
- A:
a0 b1 c2
- B:
a0 a1 b1 b2 c2 c3
- C:
a0 a1 b1 b2 b3 c3
- D:
a0 b1 c2 c3
var error = true
_ = Observable.of(1, 2, 3, 4).flatMap { v -> Observable<Int> in
if v == 2, error {
error = false
return Observable.error(TestError())
}
return Observable.of(v)
}.materialize()
.filter { $0.error == nil }
.dematerialize()
.retry()
.subscribe(onNext: { r in
print(r)
})
- A:
1 2 3 4
- B:
1 2 1 2 3 4
- C:
1 1 2 3 4
- D:
1
let one = PublishSubject<String>()
let two = PublishSubject<String>()
let source = PublishSubject<Observable<String>>()
source.switchLatest().subscribe(onNext: { value in
print(value)
})
one.onNext("1")
source.onNext(one)
two.onNext("X")
source.onNext(two)
one.onNext("2")
two.onNext("Y")
source.onNext(one)
one.onNext("3")
- A:
1 X Y
- B:
1 Y 3
- C:
Y 3
- D:
1 X 2 Y
let ob = Observable<Int>.from([1, 2]).publish()
ob.subscribe(onNext: { _ in
print("X")
})
ob.subscribe(onNext: { _ in
print("Y")
})
ob.connect()
ob.subscribe(onNext: { _ in
print("Z")
})
- A:
X Y X Y
- B:
X Y X Y
- C:
X Y Z X Y Z
- D:
X X Y Y Z Z
let pbSubject = PublishSubject<Int>()
_ = pbSubject.debounce(.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("d", $0) })
_ = pbSubject.throttle(.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("t", $0) })
pbSubject.onNext(1)
pbSubject.onNext(2)
pbSubject.onNext(3)
- A:
d1 d3 t3
- B:
t1 t3 d3
- C:
t1 d3 t3
- D:
d3 t1
let button = PublishSubject<Void>()
let textField = PublishSubject<String>()
button.withLatestFrom(textField).subscribe(onNext: { value in
print(value)
})
textField.onNext("A")
textField.onNext("B")
textField.onNext("C")
button.onNext(())
button.onNext(())
- A:
A B C C C
- B:
A A A B C
- C:
C
- D:
C C
var error = true
_ = Observable.of(1, 2, 3, 4).flatMap { v -> Observable<Int> in
if v == 2, error {
error = false
return Observable.error(TestError.test)
}
return Observable.of(v)
}.retry()
.subscribe(onNext: { print($0) })
- A:
1 2 3 4
- B:
1 2 1 2 3 4
- C:
1 1 2 3 4
- D:
1 2 3 4 1 2 3 4
let first: Single<Int> = Single.create { observer -> Disposable in
observer(.success(1))
observer(.success(2))
return Disposables.create()
}
let second: Observable<Int> = Observable.create { observer -> Disposable in
observer.onNext(3)
observer.onNext(4)
return Disposables.create()
}
_ = first.subscribe({ print($0) })
_ = first
.asObservable()
.single()
.subscribe({ print($0) })
_ = second.subscribe({ print($0) })
_ = second
.single()
.subscribe({ print($0) })
- A:
error, next(1), error, next(3), next(4), next(3), error
- B:
error, next(1), completed, next(3), next(4), next(3), error
- C:
success(1), next(1), completed, next(3), next(4), next(3), completed
- D:
success(1), next(1), completed, next(3), next(4), next(3), error
let subject = BehaviorSubject(value: 1)
let observable = subject.asObserver().debug("O").publish().refCount()
subject.onNext(2)
var subscriptions = [
observable.debug("A").subscribe(onNext: { print("A\($0)") }),
observable.debug("B").subscribe(onNext: { print("B\($0)") }),
]
subject.onNext(3)
subscriptions.popLast()?.dispose()
subject.onNext(4)
subscriptions.popLast()?.dispose()
subject.onNext(5)
subscriptions.append(observable.subscribe(onNext: { print("C\($0)") }))
subject.onNext(6)
- A:
A2 B2 A3 B3 A4 C5 C6
- B:
A2 B2 A3 B3 A4 C6
- C:
A2 A3 B3 A4 C5 C6
- D:
B3 A3 B3 A4 C5 C6
let first = PublishSubject<Int>()
let second = PublishSubject<Int>()
first.catchError({ _ in return second.catchErrorJustReturn(0) })
.subscribe({ print($0) })
.disposed(by: disposeBag)
first.onNext(1)
second.onNext(2)
first.onError(QuizError())
second.onNext(3)
first.onNext(4)
first.onError(QuizError())
second.onNext(5)
second.onError(QuizError())
second.onNext(6)
- A:
next(1) error next(3) next(5) next(0) next(6)
- B:
next(1) error next(3) next(5) next(0) completed
- C:
next(1) next(3) next(5) next(0) next(6)
- D:
next(1) next(3) next(5) next(0) completed
let first = Observable<Int>.interval(.milliseconds(200), scheduler: MainScheduler.instance)
let second = Observable<Int>.interval(.milliseconds(200), scheduler: MainScheduler.instance)
_ = first
.throttle(.milliseconds(100), scheduler: MainScheduler.instance)
.debounce(.milliseconds(500), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("A\($0)") })
_ = second
.debounce(.milliseconds(100), scheduler: MainScheduler.instance)
.throttle(.milliseconds(500), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("B\($0)") })
- A:
A0 B0 A2 B2 A5 B5 A7 B7...
- B:
B0 B2 B5 B7 B10...
- C:
A0 A2 A5 A7 A10...
- D:
(NOTHING OUTPUT)
let first = BehaviorSubject(value: 1)
let second = BehaviorSubject(value: 1)
_ = first
.asObserver().debug("A")
.delay(.milliseconds(200), scheduler: MainScheduler.instance)
.delaySubscription(.milliseconds(100), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("A\($0)") })
_ = second
.asObserver().debug("B")
.delaySubscription(.milliseconds(200), scheduler: MainScheduler.instance)
.delay(.milliseconds(100), scheduler: MainScheduler.instance)
.subscribe(onNext: { print("B\($0)") })
first.onNext(2)
second.onNext(2)
- A:
A1 A2 B1 B2
- B:
A1 A2 B2
- C:
B2 A2
- D:
A2 B2
let first = PublishSubject<Int>()
let second = PublishSubject<Int>()
let third = PublishSubject<Int>()
_ = Observable<Int>
.amb([first.asObservable(), second.asObservable()])
.catchError({ _ in third.asObservable()})
.subscribe{ print($0) }
first.onError(QuizError())
second.onNext(2)
third.onNext(3)
second.onError(QuizError())
third.onNext(4)
- A:
next(2) error
- B:
next(2) next(3) next(4)
- C:
next(3) next(4)
- D:
next(3) error
let first = PublishSubject<Int>()
let second = PublishSubject<Int>()
_ = first
.asObservable()
.timeout(.milliseconds(200), scheduler: MainScheduler.instance)
.delay(.milliseconds(400), scheduler: MainScheduler.instance)
.catchError({ _ in return Observable.empty()})
.ifEmpty(switchTo: second)
.subscribe({ print($0) })
first.onNext(1)
second.onNext(2)
- A:
next(1)
- B:
next(2)
- C:
next(1) next(2)
- D:
(NOTHING OUTPUT)
let first = PublishSubject<Int>()
let second = PublishSubject<Int>()
_ = first
.asObservable()
.timeout(.milliseconds(200), scheduler: MainScheduler.instance)
.delay(.milliseconds(400), scheduler: MainScheduler.instance)
.catchError({ _ in return Observable.empty()})
.ifEmpty(switchTo: second)
.subscribe({ print($0) })
first.onNext(1)
second.onNext(2)
first.onCompleted()
- A:
next(1)
- B:
next(2)
- C:
next(1) next(2)
- D:
(NOTHING OUTPUT)