let s = "Hello World"
let string = BehaviorSubject(value: s)
//Example 1
string
.map { _ in "hhh" }
.subscribe(onNext: { element in
print(element)
}, onCompleted: {
print("completed")
}
)
//Example 2
string
.flatMap { s -> Observable<String> in
Observable.just("lll")
}
.subscribe(onNext: { element in
print(element)
}, onCompleted: {
print("completed")
}
)
//Example 3
let aaa = string
.map { _ in "hhh" }
//Example 4
let bbb = string
.flatMap { s -> Observable<String> in
Observable.just("lll")
}
在示例1和2中,我是RX世界的新手,我使用
map
和flatMap
进行测试以测试这种行为。它们之间的主要区别之一是map
返回正常值类型,而flatMap
返回Observable类型。在示例3和示例4中,它显示
aaa
和bbb
的类型均为Observable<String>
..现在,由于最后它们变成了同一件事,为什么您甚至还需要
flatMap
返回特定的Observable
类型?还是为什么需要map
返回normal value
类型?(我知道
flatMap
可以做其他事情,这不是这种混乱的一部分) 最佳答案
map
运算符用于转换值并将转换后的值传递给下一个运算符,当flatmap
展平可观察对象的层次并将其公开为单个运算符时
map
和flatmap
的用例
通常,如果要转换在当前运算符中接收到的值并将其通常同步地传递给下一个运算符,则可以使用map
。无论您为BehaviorRelay
分配了什么值,示例示例都想返回“hhh”,这是直接的同步值转换,因此String
有意义
string
.map { _ in "hhh" }
.subscribe(onNext: { element in
print(element)
}, onCompleted: {
print("completed")
}
)
map
用于展平可观察对象的层次结构,并将其作为单个可观察对象简单地公开给下一个运算符。该示例假定您正在实现搜索,一旦触发该值,您就想进行API调用并将响应传递给下一个运算符。现在进行API调用是一个异步操作,您知道简单的flatmap
不会通过,那么您可以使用map
let string = BehaviorRelay<String>(value: "abcd")
string
.flatMap { s -> Observable<Response> in
return Observable<Response>.create({ (observer) -> Disposable in
//make api call here
//pass data / error using observer.onNext or observer.onError()
return Disposables.create()
})
}
.subscribe(onNext: { element in
print(element)
}, onCompleted: {
print("completed")
}
)
因此,这里的实际API调用是由
flatmap
运算符内部的observable进行的,但是对于外部世界,它看起来像BehaviorRelay本身将字符串类型的值转换为Response。这是完美的,因为不需要知道进行API调用所涉及的实质:)
但说实话,如果您确实要实现搜索,则宁愿选择
flatMap
而不是flatMapLatest
。阅读有关flatmap
和flatMap
的更多信息,以更好地理解:)