Here's one idea, basically put "channel on a channel" idea:

(defonce main-c (chan 1))


(defn start-main-channel-loop []
  ;put channels on the channel in the order that they need to execute
  (go
    (loop []
      (let [c (<! main-c)                                   ;wait for channel 
from the main channel
            x (<! c)]                                       ;wait for 'x' from 
channel 'c'
        ;do stuff with x, it can dispatch based on the data that is 'x'
        (println "x ::: " x)
        (recur)))))

(comment
  (let [i-run-before-callback-c (chan 1)                   
        callback-c (chan 1)]
       ;"schedule" things to run in desired order
       (put! main-c i-run-before-callback-c)
       (put! main-c callback-c)

       ;run in go to ensure order of events
       (go
         ;>! this first
         (>! callback-c [:second {}])
         ;wait 3 seconds for demo purposes
         (<! (timeout 3000))
         ;>! this second
         (>! i-run-before-callback-c [:first {}]))))


After about 3 seconds you should see this printed:

*x :::  [:first {}]*
*x :::  [:second {}]*

... i.e. even though we scheduled *[:second {}]* before *[:first {}]*, they 
appear in the desired order at the end.



On Friday, May 3, 2019 at 1:47:10 AM UTC-7, Tom Locke wrote:
>
> In the early core.async presentation, Rich argues that we should avoid 
> putting application logic in callback handlers, and instead build the 
> "machine like" parts of our code in the core.async model. To bridge from 
> callback world to core.async we have put! and take! which we should call as 
> soon as possible.
>
> But what do we do if the library we are interfacing with relies on some 
> effect having happened *before* the callback returns, but our application 
> architecture dictates that effect should come from some other process? (go) 
> (put!) and (take!) all return immediately.
>
> According to my (hopefully incorrect!) understanding, it's not possible.
>
> It seems to me we need something like (<!!), which is not available in 
> cljs due to the lack of real threads.
>
> However, could we not have an implementation of (<!!) that goes something 
> like this?:
>
> (defn <!! [c] 
>   (loop
>    (or (poll! c)
>        (if (any-process-ready?)
>          (do 
>            (schedule-next-process!)
>            (recur))
>          (throw "deadlock!")))))
>
> This is making some uninformed assumptions about the scheduler, but 
> presumably there must be:
>
>   - Some kind of list of ready (not blocked on channel operations) 
> processes
>   - The ability to run a ready process until the next scheduling point (or 
> until it runs out of processes).
>
> However I believe the scheduler is to be considered private/opaque, so a 
> proper "userland" implementation would not be possible.
>
>

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at https://groups.google.com/group/clojurescript.

Reply via email to