@@ -141,7 +141,8 @@ Let us rewrite this code using [publish] coroutine builder from `kotlinx-corouti
141
141
instead of [ produce] from ` kotlinx-coroutines-core ` module. The code stays the same,
142
142
but where ` source ` used to have [ ReceiveChannel] type, it now has reactive streams
143
143
[ Publisher] ( https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Publisher.html )
144
- type.
144
+ type, where [ consumeEach] was used to _ consume_ elements from the channel,
145
+ now [ collect] [ org.reactivestreams.Publisher.collect ] is used to _ collect_ elements from the publisher.
145
146
146
147
<!-- - INCLUDE
147
148
import kotlinx.coroutines.*
@@ -194,15 +195,15 @@ Begin
194
195
195
196
This example highlights the key difference between a reactive stream and a channel. A reactive stream is a higher-order
196
197
functional concept. While the channel _ is_ a stream of elements, the reactive stream defines a recipe on how the stream of
197
- elements is produced. It becomes the actual stream of elements on _ subscription _ . Each subscriber may receive the same or
198
+ elements is produced. It becomes the actual stream of elements when _ collected _ . Each collector may receive the same or
198
199
a different stream of elements, depending on how the corresponding implementation of ` Publisher ` works.
199
200
200
- The [ publish] coroutine builder, that is used in the above example, launches a fresh coroutine on each subscription.
201
- Every [ Publisher. collect] [ org.reactivestreams.Publisher.collect ] invocation creates a fresh subscription .
201
+ The [ publish] coroutine builder, that is used in the above example, does not launch a coroutine,
202
+ but every [ collect] [ org.reactivestreams.Publisher.collect ] invocation launches a coroutine .
202
203
We have two of them in this code and that is why we see "Begin" printed twice.
203
204
204
- In Rx lingo this is called a _ cold_ publisher. Many standard Rx operators produce cold streams, too. We can iterate
205
- over them from a coroutine, and every subscription produces the same stream of elements.
205
+ In Rx lingo this is called a _ cold_ publisher. Many standard Rx operators produce cold streams, too. We can collect
206
+ them from a coroutine, and every collector gets the same stream of elements.
206
207
207
208
** WARNING** : It is planned that in the future a second invocation of ` consumeEach ` method
208
209
on an channel that is already being consumed is going to fail fast, that is
@@ -217,10 +218,10 @@ method with it.
217
218
218
219
### Subscription and cancellation
219
220
220
- An example in the previous section uses ` source.collect { ... } ` snippet to open a subscription
221
- and receive all the elements from it. If we need more control on how what to do with
222
- the elements that are being received from the channel, we can use [ Publisher.collect ] [ org.reactivestreams.Publisher.collect ]
223
- as shown in the following example :
221
+ An example in the previous section uses ` source.collect { ... } ` to collect all elements.
222
+ Instead of collecting elements, we can open a channel using [ openSubscription ] [ org.reactivestreams.Publisher.openSubscription ]
223
+ and iterate over it, so that we have more finer-grained control on our iteration,
224
+ for example using ` break ` , as shown below :
224
225
225
226
<!-- - INCLUDE
226
227
import io.reactivex.*
@@ -259,17 +260,16 @@ Finally
259
260
```
260
261
261
262
<!-- - TEST -->
262
-
263
+
263
264
With an explicit ` openSubscription ` we should [ cancel] [ ReceiveChannel.cancel ] the corresponding
264
- subscription to unsubscribe from the source. There is no need to invoke ` cancel ` explicitly -- under the hood
265
- ` consume ` does that for us.
265
+ subscription to unsubscribe from the source, but there is no need to call ` cancel ` explicitly -- under the hood
266
+ [ consume] does that for us.
266
267
The installed
267
268
[ doFinally] ( https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#doFinally(io.reactivex.functions.Action) )
268
269
listener prints "Finally" to confirm that the subscription is actually being closed. Note that "OnComplete"
269
270
is never printed because we did not consume all of the elements.
270
271
271
- We do not need to use an explicit ` cancel ` either if iteration is performed over all the items that are emitted
272
- by the publisher, because it is being cancelled automatically by ` collect ` :
272
+ We do not need to use an explicit ` cancel ` either if we ` collect ` all the elements:
273
273
274
274
<!-- - INCLUDE
275
275
import io.reactivex.*
@@ -284,7 +284,7 @@ fun main() = runBlocking<Unit> {
284
284
.doOnSubscribe { println (" OnSubscribe" ) } // provide some insight
285
285
.doOnComplete { println (" OnComplete" ) } // ...
286
286
.doFinally { println (" Finally" ) } // ... into what's going on
287
- // iterate over the source fully
287
+ // collect the source fully
288
288
source.collect { println (it) }
289
289
}
290
290
```
@@ -684,8 +684,8 @@ fun <T, U> Publisher<T>.takeUntil(context: CoroutineContext, other: Publisher<U>
684
684
other.openSubscription().consume { // explicitly open channel to Publisher<U>
685
685
val other = this
686
686
whileSelect {
687
- other.onReceive { false } // bail out on any received element from `other`
688
- current.onReceive { send(it); true } // resend element from this channel and continue
687
+ other.onReceive { false } // bail out on any received element from `other`
688
+ current.onReceive { send(it); true } // resend element from this channel and continue
689
689
}
690
690
}
691
691
}
@@ -1068,6 +1068,7 @@ coroutines for complex pipelines with fan-in and fan-out between multiple worker
1068
1068
[ consumeEach ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/consume-each.html
1069
1069
[ ReceiveChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/index.html
1070
1070
[ ReceiveChannel.cancel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/cancel.html
1071
+ [ consume ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/consume.html
1071
1072
[ SendChannel.send ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/send.html
1072
1073
[ BroadcastChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-broadcast-channel/index.html
1073
1074
[ ConflatedBroadcastChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-conflated-broadcast-channel/index.html
@@ -1078,6 +1079,7 @@ coroutines for complex pipelines with fan-in and fan-out between multiple worker
1078
1079
<!-- - INDEX kotlinx.coroutines.reactive -->
1079
1080
[ publish ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/kotlinx.coroutines.-coroutine-scope/publish.html
1080
1081
[ org.reactivestreams.Publisher.collect ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/collect.html
1082
+ [ org.reactivestreams.Publisher.openSubscription ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/open-subscription.html
1081
1083
<!-- - MODULE kotlinx-coroutines-rx2 -->
1082
1084
<!-- - INDEX kotlinx.coroutines.rx2 -->
1083
1085
[ rxFlowable ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-rx2/kotlinx.coroutines.rx2/kotlinx.coroutines.-coroutine-scope/rx-flowable.html
0 commit comments