I'm having some difficulty understanding the output of the following code sample.
(def ch (a/chan 1))
(a/go-loop []
(Thread/sleep 1000)
(a/onto-chan ch [1 2 3 4 5] false)
(recur))
(a/go-loop []
(Thread/sleep 500)
(let [val (a/<! ch)]
(println val))
(recur))
What I expected to see was a 500ms delay between each number that is printed to the REPL, receiving the numbers 1-5 in order before another range starts printing.
However, it appears as though the numbers are interleaving when introducing the Thread/sleep into the go-block that reads from the channel. I was under the impression that items are retrieved from a channel in the same order they are put onto the channel?
Is there something I'm missing?
onto-chan
executes asynchronously. Each execution of your first go-loop
basically starts a new process, putting values onto the channel in parallel. Note the documentation, which states Returns a channel which will close after the items are copied.
If you wait for onto-chan
to finish, you get the expected result:
(def ch (async/chan 1))
(async/go-loop []
(Thread/sleep 1000)
(async/<! (async/onto-chan ch [1 2 3 4 5] false))
(recur))
(async/go-loop []
(Thread/sleep 500)
(when-let [val (async/<! ch)]
(println val)
(recur)))