14

I'm learning RxSwift and I've come across the following pattern when creating Observables:

return Observable.create { observer in

    let disposable = Disposables.create()

    // Do some stuff with observer here

    return disposable
}

As far as I can tell the returned Disposable doesn't actually do anything, does it serve a purpose other than to meet the requirements of the API to return a Disposable?

Is there any scenario where you might need to return a configured Disposable?

I suppose the thing that's confusing me the most is that the returned Disposable seems separate from the implementation of the Observable being created, i.e. it's not assigned to any properties or passed anywhere it's just created and returned.

mike
  • 2,073
  • 4
  • 20
  • 31
  • 3
    Side note, the thing that is passed into your closure is an Observer not an Observable. So you should be writing `Observable.create { observer in` instead. – Daniel T. Aug 31 '18 at 15:00

2 Answers2

14

There are two variations of the create method in relation to Disposables.

The first one, as Daniel mentioned, is used when you create a new Observable; you'll use the Disposables.create { ... } closure to "do cleanup", basically.

This is highly useful when using flatMapLatest, as your previous request will be disposed when a new ones comes in. Whenever it would be disposed, that "clean up" block will be called.

Observable<Int>.create { observer in
    let someRequest = doSomeLongRunningThing { result in
        observer.onNext(result)
        observer.onCompleted()
    }

    return Disposables.create {
        // How can I "cleanup" the process?
        // Cancel the request, for example.
        someRequest.cancel()
    }
}

The second variation of Disposables.create is used for an entirely different purpose - grouping several Disposable objects as a single disposable object (a CompositeDisposable).

For example:

let disposable1 = someAction()
let disposable2 = someOtherAction()

let compositeDisposable = Disposables.create(disposable1, disposable2)
Shai Mishali
  • 9,224
  • 4
  • 56
  • 83
9

The Disposables.create function takes an optional closure. You should put any cancelation code in that closure. If you don't have any way to cancel, then the code is empty.

A good example is the wrapper around URLSession's dataTask method. In non-Rx code when you call URLRequest.shared.dataTask it returns a URLSessionDataTask object which can be used to cancel the network call. That object's cancel function gets called in the disposable.

Another common use is when you subscribe to some other observable from within your create closure. You then have to pass the disposable from that/those subscriptions by returning a Disposables.create(myDisposable) So that those subscriptions will get canceled properly when your Observable is disposed of.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • That explains a lot. Why is it the returning element though? Aren't we trying to return an observable? – mfaani May 28 '19 at 17:34
  • 1
    We are not trying to _return_ an Observable, we are _creating_ an Observable. If you had to create and return an Observable from inside the Observable's creator function, you would get stuck in an infinite regress. – Daniel T. May 29 '19 at 01:00
  • 1
    If I only subscribe one observable(myDisposable), can I directly return `myDisposable`, as it seems equal to `return Disposables.create(myDisposable)`? – Saafo Aug 09 '23 at 09:44
  • 1
    @Saafo That is correct. – Daniel T. Aug 09 '23 at 11:39