4 ms·
Asynchronous Error Handling
- film42 13y agoThis is a very interesting idea. Although I still prefer the "jquery" way of passing in success/ failure as options. In fact, depending on what framework I'm using, I even trigger a success or failure event so it looks more like.. model.fetch(); model.on('error', function() { throw new Error(); }); But this article really got me thinking though, thank you!
- ryanto 13y agoThe problem with passing success/failure as options is they don't compose well. Try to write the twitter example in the blog post this way. Then try to abstract each step as a reusable piece. And lastly have a mechanism for handling errors at any step. This looks ugly and is hard to follow. Promises (or generators) provide an API for thinking about async code as composable parts, which leads to easier to understand functions.
- abecedarius 13y agoThis criticizes promises on two grounds: they need to propagate and handle errors, and the Javascript syntax looks different from the corresponding sequential code. OTOH with channels, if I understand it, the system needs to propagate and handle errors ("If an asynchronous process writes an error onto its channel we will convert it into an exception") -- can you explain the advantage? And the better syntax we're offered is ClojureScript or yield. For a cleaner comparison we should avoid unnecessary differences in the code. Let's fix that: getTweetsFor("swannodette") .then(function (tweets) { return expandUrl(parseUrls(tweets)[0]); }) .then(httpGet) .then( function (responseBody) { console.log("Most recent link text:", responseBody); }, function (error) { console.error("Error with the twitterverse:", error); } ); Besides yield, ES6 has shorter function expressions (you can try them right now in Firefox): getTweetsFor("swannodette") .then(tweets => expandUrl(parseUrls(tweets)[0])) .then(httpGet) .then(responseBody => console.log("Most recent link text:", responseBody), error => console.error("Error with the twitterverse:", error)); I'd agree that this could be better still; I'd like either built-in syntax dealing with promises, like E had 15 or so years ago, or something more general like Haskell's do-notation. But yield seems nice too.
- swannodette 13y agoThanks for the cleanup though I think it's easy to see it's not much of an improvement. It's also not really equivalent to the core.async / ES6 Generator version as the error must propagate through the promise pipeline instead of short circuiting as it would thrown as a real exception. UPDATE: also see the comment below about stack traces. Since we don't have to wrap promises at every step of the pipeline you can recover much cleaner stack traces devoid of useless promise machinery. Which leads us to the points from my other post about the problem with promises :) While this is fine for coarse grained asynchrony like this example - the allocation overheads for each step of the pipeline is unacceptable for say mouse events - forcing you to leverage another abstraction like Rx. So does JS need sugar for both promises & async streams? I should hope not, and core.async / ES6 Generators demonstrate that you don't need two different abstractions and you can get a lot more efficiency and less error indirection than promises can possibly offer. This is more or less what Erik Meijer's been saying about C# async/await for a long time now.
- abecedarius 13y agonot much of an improvement I just wanted our thumbs off the scale. the error must propagate through the promise pipeline instead of short circuiting Along a queue vs. up a stack, I'm not sure there's a fundamental efficiency difference, if that's what you're saying. Maybe. When it comes to distributed apps, OTOH, just one round trip saved by automatic promise pipelining http://erights.org/elib/distrib/pipeline.html http://erights.org/elib/distrib/pipeline.html can outweigh a lot of that sort of thing. stack traces That post says Q's stack traces are fine if you set a flag, and the same for generator-based libraries (optional because it costs extra). I expect ClojureScript does better because it can compile its own code, and the same would go for a promise-based language (or JS preprocessor). So this is what you were getting at with "needs to propagate and handle errors" vs. ClojureScript -- you're saying the latter's more efficient? does JS need sugar for both promises & async streams? I'm not sure what you mean about async streams, but I wasn't seriously after more changes to JS syntax, just wishing (1) E had taken off and (2) new languages learn from it.
- 13y ago
- spion 13y agoI wrote a detailed comparison of JS async coding patterns here (emphasis on ES6 generators): http://spion.github.io/posts/analysis-generators-and-other-async-patterns-node.html http://spion.github.io/posts/analysis-generators-and-other-a... Unfortunately most patterns that consolidate error handling also result with useless stack traces, or have to resort to performance-reducing trickery (Q). This also includes generators.
- swannodette 13y agoThis is another problem with promises is the the mangling of the stack trace. In my version the stack traces are more or less left clean since you don't have to wrap at every step of your async pipeline.
- MaxGabriel 13y agoswannodette, would you consider upping the font size 1-3px? The font is very thin and I found it hard to read at even 15px.
- AndreasFrom 13y agoI agree. I find Computer Modern to be more suited for mathematics and making it justified as well is not good for readability.
- nimish 13y agoBut TeX justifies (and hyphenates and microtypes...) by default? I'm curious why it would hurt legibility. It's the default text font for non-math stuff there too
- rzimmerman 13y agoThis would be the equivalent in Kal: http://goo.gl/TwsL2h http://goo.gl/TwsL2h It's a different approach, but it doesn't require ES6 or any libraries (once compiled). Forgive the slight funkiness with the indentation. try wait for tweets from getTweetsFor "swannodette" url = parseUrls(tweets)[0] wait for responseBody from httpGet url print "Most recent link text: " + responseBody catch error console.error "Error with the twitterverse: " + error
- swannodette 13y agoThis is nice but I am of course biased about the CSP model. While `wait` is good for one off tasks, I now prefer CSP channels as they just as easily capture Rx style interactive event programming.
- markus2012 13y agoThere is a problem with relying on setImmediate() in your channel implementation: 1. httpGet... 2. setImmediate() in a tight loop using 100% CPU until httpGet() returns ... I'd rather not burn ~100% CPU for what could be a couple of seconds waiting for a slow web server (even if we're nicely burning it).