** Is there a more idiomatic way? **
Here is a cut down version built from a fresh template:
If you run this code, you don't see the thinking deeply countdown, and you cannot click the other button.
If you uncomment the timeout 1, it works better.
(defn hello-world []
[:div
[:h1 (:text @app-state)]
[:button
{:on-click
(fn [e]
(swap! app-state assoc :thinking true :thinking-deeply 5)
(go
(while (pos? (:thinking-deeply @app-state))
;(<! (timeout 2000))
(apply * (rest (range 10000000)))
;(<! (timeout 1))
(swap! app-state update :thinking-deeply dec))
(swap! app-state dissoc :thinking :thinking-deeply)))}
"The button!"]
(when (:thinking-deeply @app-state)
[:h2 "Thinking deeply " (:thinking-deeply @app-state)])
(when (:thinking @app-state)
[:h2 "Thinking"])
[:button "The other button"]])
Full source code is attached
Regards,
Timothy
--
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 clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.
What the timeout achieves is that you give some control back to the browser so instead of 1sec "blocking" you get 5x200ms blocking. Still far from 60fps but better than 0.
If you want to do CPU intensive work without blocking the UI you'll need to use one or more WebWorkers. You could layer core.async on top of that to communicate between the Workers and the UI but core.async itself does nothing in that regard.
WebWorkers are pretty easy to get going but carry their own set of drawbacks so it is very dependent on your use case whether they make sense or not.
HTH,
/thomas
While that is correct let me emphasize that timeout is not a solution!
Do you always know how long task X will run or whether you are going to need to chunk it? Is it even possible to split up? A "task" that may complete in 10ms on your machine might take 100ms on another one or even 500ms on yours if the computer is doing something else.
If you need to do CPU intensive work in the browser use a WebWorker. It is their purpose. While not perfect it is far better than trying to be "cooperative" in your code.
My 2 cents,
/thomas
You have a problem, and you decide to solve it via webworkers.
Later you'll WISH you'd chosen regexs instead :-)
--
Mike
--
Mike
--
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 clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.
Well, while we are on the topic perhaps we should mention the downside of using Web Workers. For me it has been Data Transfer.
Since you can only transfer JSON type data between workers that usually meant you had to pr-str/read-string to roundtrip CLJS data. If you only have very small amounts of data that is no problem but read-string is not very performant and even something like 1mb of data will eat up enough CPU time to drop you below 60fps.
That might now be worked around with transit though since that is much faster. But still if you need to transfer a lot of data between workers you might be better of not using them. IE8/9 might also be an issue but even Microsoft suggest that you should not support those versions.
Oh and so far I have not seen support for workers in lein-cljsbuild and I haven't documented anything in shadow-build so building web worker javascript files might actually be something of a mystery to people. To be honest I never used them for anything other than toy projects either.
Anyways, I like them. Use them. It is not that hard. :)
Cheers,
/thomas
>
> Why the cynicism? Isn't it true that the only way to make use of multiple cores in browser is to use WebWorkers?
>
>