Skip to content

Instantly share code, notes, and snippets.

@jamiepinkham
Last active June 8, 2019 04:19
Show Gist options
  • Save jamiepinkham/9208d351e3b9eba0aa622729791d767b to your computer and use it in GitHub Desktop.
Save jamiepinkham/9208d351e3b9eba0aa622729791d767b to your computer and use it in GitHub Desktop.
enum MyError: Error {
case whoops
}
//Observable.create {}
let o = AnyPublisher<Int, MyError> { subscriber in
/*
onNext, but in combine you are returned a demand,
this is for controlling backpressure, which
doesn't exist in RxSwift.
someone on the combine team mentioned the implementation
was more inspired by Reactive Streams implementations
(think Akka) where backpressure is a thing.
there's a very good reason apple chose this, because
it's a weird concept for sure
*/
let demand = subscriber.receive(1)
print(demand)
let _ = subscriber.receive(2)
let _ = subscriber.receive(3)
let _ = subscriber.receive(4)
//onComplete
subscriber.receive(completion: .finished)
/*
alternatively if you want to send an error,
although it appears you can send both a completion and
a failure and the runtime doesn't seem to care
in RxSwift, this would assert in debug
subscriber.receive(completion: .failure(.whoops))
*/
}
/*
ok now is where things get weird.
i'll explain this optional later.
*/
var s: Subscribers.Sink<AnyPublisher<Int, MyError>>? = nil
/*
subscribe(onNext:{}, onError: {}, onCompleted: {})
but combine sends the complete/error events to the same closure,
and it's the first argument, probably because the most common use case is just
the onNext case. e.g., o.sink { val in print(val) }
*/
s = o.sink(receiveCompletion: { result in
switch result {
case .finished:
print("completed")
case let .failure(f):
print("error \(f)")
}
}, receiveValue: { int in
print(int)
})
/*
silencing a compiler warning, "s" is never read
*/
print(String(describing:s))
/*
Subscribers have reference type semantics (are classes) so disposal follows the same rules as ARC
setting this to nil disposes the subscription.
BUT!!! not in this code because everytning is running on the immediate scheduler.
* i think *
*/
s = nil
/*
things like Observable.just, Observable.empty are found in the Publishers enum
so like Observable.just is Publishers.Just, Observable.empty is Publishers.empty
there's a futures like creator, that is like a single: Publishers.Future
*/
@jamiepinkham
Copy link
Author

jamiepinkham commented Jun 7, 2019

Some caveats:

  • I am not at WWDC, and haven't seen any of the Combine sessions
  • I do not think this is the idiomatic way to use Combine. I think that Apple expects you create objects that are Publisher and Subscriber conforming, and wire up your pipelines that way, somewhat like Akka Streams.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment