Chapter 8. Asynchronous Processing

In this chapter, you will write an étude that uses core.async to do asynchronous processing. Even though the JavaScript environment is single-threaded, core.async allows you to work with anything that needs to be handled asynchronously; this is a very nice feature indeed.

Here are two examples of using core.async. In the first example, Annie and Brian are going to send each other the numbers 5 down to zero, stopping at zero, in a project named async1. You will need to add some :require and :require-macro specifications to your namespace:

(ns ^:figwheel-always async1.core
  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
    (:require [cljs.core.async
               :refer [<! >! timeout alts! chan close!]]))

Then, define a channel for both Annie and Brian:

(def annie (chan))
(def brian (chan))

Annie gets two processes: one for sending messages to Brian and another for receiving messages from him:

(defn annie-send []
  (go (loop [n 5]
           (println "Annie:" n "-> Brian")
           (>! brian n)
           (when (pos? n) (recur (dec n))))))

(defn annie-receive []
  (go-loop []
           (let [reply (<! brian)]
             (println "Annie:" reply "<- Brian")
             (if (pos? reply)
               (recur)
               (close! annie)))))

In the annie-send function, you see the go function, which asynchronously executes its body and immediately returns to the calling function. The >! function sends data to a channel. The loop continues until n equals zero, at which point the function returns nil.

Because go and loop occur together ...

Get Etudes for ClojureScript now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.