defer
有人可以解释一下和create
方法之间的区别Observable
吗?我不明白什么时候应该使用defer
,什么时候应该使用create
..
参考:
推迟:http ://reactivex.io/documentation/operators/defer.html
创建:http ://reactivex.io/documentation/operators/create.html
谢谢
defer
有人可以解释一下和create
方法之间的区别Observable
吗?我不明白什么时候应该使用defer
,什么时候应该使用create
..
参考:
推迟:http ://reactivex.io/documentation/operators/defer.html
创建:http ://reactivex.io/documentation/operators/create.html
谢谢
因此,区别似乎是:defer
当您已经拥有创建/返回可观察对象的东西时很好,但是您不希望该过程在订阅之前发生。
create
当您需要手动包装异步进程并创建 observable 时,这是很好的选择。该创建也推迟到订阅。
换一种方式:
defer
是一个能够延迟组合可观察序列的运算符。
create
是可观察序列的自定义实现(创建被推迟到订阅)。
因此,如果您有可能使用从某些结果/值just
创建一个的情况,Observable
或者您有一个返回Observable
请求的网络 API 层,但您不希望该请求在订阅之前启动。defer
对于那些场景会很好。
如果你有一个网络 API 层不返回Observable
请求,但你需要一个Observable
接口,你可以使用create
. 该Observable
序列仍然不会在订阅之前创建。如果您希望无论订阅如何都启动该网络调用,那么您将使用不同的机制,例如 a Subject
,可能会重播。
create(...) 实际上会立即创建 Observable。
public final static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(hook.onCreate(f));
}
defer(...) 接受返回 Observable(Subject, etc...) 的 Factory 函数,用 OnSubscribeDefer 包装它并仅在订阅者订阅时创建 Observable,为每个订阅者创建新的 Observable。
public final static <T> Observable<T> defer(Func0<Observable<T>> observableFactory) {
return create(new OnSubscribeDefer<T>(observableFactory));
}
在此处查看更多详细信息
以示例的方式,对上面已经给出的非常好的答案进行了另一种看法。
假设您有一个基于其内部状态返回 Observable 的类(用类似 Javascript 的伪语言编写,但适用于所有 ReactiveX 实现)
class DownloadManager {
var uuid = nil // this only gets set during runtime...say when a user performs a certain action
// fetches some data from the server.
func get() -> Observable<Data> {
if uuid == nil {
return .error(new DownloadUuidEmptyError())
}
return network.download(uuid, ...) // do something with the non nil uuid
}
}
以这种方式编写,可能会调用该方法,并且在实际评估它之前传递 observable,并且 uuid 可能在方法调用时不存在,但在订阅 Observable 时存在,从而产生错误。
let observable = manager.get()
// ... at some point, uuid is assigned to
// then we subscribe to our observable ...
observable.subscribe(...).disposedBy(bag) // errors!
在这种情况下,defer 可以派上用场,以确保在订阅时间之前不会进行评估(例如 uuid)。
// fetches some data from the server.
func get() -> Observable<Data> {
return Observable.defer {
if uuid == nil {
return .error(new DownloadUuidEmptyError())
}
return network.download(uuid, ...) // do something with the non nil uuid
}
}
现在,上面的示例将不再出错。也许更大的目标是确保您的代码永远不会达到这种状态,但有时它并不实用。这种模式对我来说很方便。