4 ms·
Why don't you go further and try/catch that to make it usable in a real app? How do you handle async errors?
by ilostmykeys 11y ago
Why don't you go further and try/catch that to make it usable in a real app? How do you handle async errors?
- Skinney 11y agoInstall an exception handler on the channel or return exceptions on the channel. The latter is more common. I've written my own macros to make the latter case pleasant (<10 loc), but I believe the go-catching and <? macros from glossop provide the same functionality. (defmacro go-catching [& body] `(go (try ~@body (catch js/Error e# e#)))) (defmacro <? [chan] `(let [res# (<! chan)] (if (instance? js/Error res#) (throw res#) res#))) Used like this: (go-catching (<? (async-fn)))
- ilostmykeys 11y agoCan you expand that to the concurrent scenario? Show us how you implement this simple and very common concurrent pattern with ClojureScript. I've seen stuff that implement this in ClojureScript and it ain't pretty (to say the least) Impress me! :) In ES7: async function fAsync() { try { var results = await Promise.all([asyncOpA, asyncOpB, asyncOpC]) } catch (e) { ... } }
- yogthos 11y agoimpressed? :) https://funcool.github.io/promesa/latest/#error-handling https://funcool.github.io/promesa/latest/#error-handling
- deleted 11y ago[deleted]
- ilostmykeys 11y agoI couldn't find example in the docs for that library showing concurrent async ops with simple try/catch type error handling. So it's still not clear to me how you would rewrite the above shown async/await concurrent scenario using this library.
- mad-mad-beaver 11y agoJust use promesa/all then catch :) Moreover, it has funcool/cats bindings, so you can use promises in mlet and alet macros if you are into monad thing ;)
- ilostmykeys 11y agoOh right, that makes sense but does not make async code organize the way synchronous code does (as async/await sugar enables) but is a fair deal if you don't mind your async code using a different organizing pattern or if you specifically want it to be that way... :) Re: cats Not a big fan of abstractions that don't contribute to code simplicity. What is the percentage of programmer who dig monads? Less than 1% probably.
- Skinney 11y agoIt's a trivial matter to wrap promise/all in a core.async channel, providing the exact orginzation pattern you're looking for.
- ilostmykeys 11y agoShow me the code! Go ahead and let's see how pretty that is, and son't forgeg error handling and concurrency.
- Skinney 11y agoI've provided all the code you need to put the pieces together quite trivially. Using go-catching, <? and the promise library (or just the core.async snippet I wrote earlier), you should be able to write the following: (go-catching (<? (async-all [asyncOpA asyncOpB asyncOpC]))) And yes, that handles errors exactly like synchronous code does. The total number of lines for implementing go-catching, <? and async-all shouldn't take more than 20-30 loc, if not less. Now, if 20-30 loc is too much for you to write, then by all means use JS.
- 11y ago
- Skinney 11y agoFrom reading core.asyncs documentation, it sounds like this should do the trick: (go (try (let [ops [asyncOpA asyncOpB asyncOpC]] (core.async/take (count ops) (apply core.async/merge ops))) (catch js/Error e ...))) Where asyncOp* uses go-catching.