5 ms·
This is precisely my concern, and I have talked to a lot of people regarding this exact point. I think node.js is really cool but I would love if this was just
by tolmasky 17y ago
This is precisely my concern, and I have talked to a lot of people regarding this exact point. I think node.js is really cool but I would love if this was just built into the language, such that code would perform asynchronously but not move to the next line.
var a = something_async(), b = something_else_async();
Upon calling something_async, the code starts waiting and blocks further execution until it is ready, going to the next statement. This is not a foreign concept at all, and is used in javascript as well with alert, prompt, confirm:
fries = window.confirm("Do you want fries with that?")
confirm is an async method (has to wait for the user), but the next line is not executed until it returns. I personally see no advantage to creating a system of callbacks:
do_x(function () { do_y(function() { do_z() }) })
when this would be much more readable:
do_x();
do_y();
do_z();
and would have the exact same perf characteristics. In fact, you could probably simpy code transform the latter into the former (I know this is what stratified JS does), although this is probably the worst way to do it. What you really want is to just auto-call "wait" on every promise (I believe wait still gives you the asynchronous benefits).
Of course, the main "drawback" to this is that you need language support to pull it off, so you need to implement a preprocessor of some sort.
- _sh 17y agoI don't understand your concern. When you say 'Upon calling something_async, the code starts waiting and blocks further execution until it is ready', you're describing a synchronous call. Indeed window.confirm is a synchronous function--nothing is executed until it returns. And yes, both asynchronous and synchronous operations have their place, umm, except perhaps in Haskell where things get funky. Chaining async operations together in javascript can be tedious, but its easy enough to write a helper function to handle it for you. Every javascript app I've written that uses AJAX always has some form of createCallback(context, function, arguments) function.
- xal 17y agoRe-read my example. All 3 db queries are run in parallel however the code does not continue if you access one of the values until the value is available. In a typical web application you usually get 3-5 things from the db, then you start rendering the templates. Each DB query waits for completion, then it starts the next which is a huge waste of time. In fact the system can easily start the parser and template renderer while the DB queries run and all the data will likely be available once it's accessed. This means you have all the benefits of synchronous processing with the majority of the advantages of async. The vast majority of web applications would likely very rarely block a thread in such an architecture. I'm very surprised that not more languages implement this pattern. Maybe i'm missing something but this is the major feature of GO, except that almost everyone missed it and focused on the fact that it compiles fast and looks like c
- Hexstream 17y agoSeems like you the dataflow paradigm is exactly what you'd need. With dataflow, trying to read a variable that doesn't know its value yet blocks until the value becomes known.
- swannodette 17y agoYou don't need language support and you don't even need a preprocessor. You just need to define a custom event system. do_x(); do_y(); do_z(); Ideally those three should not even be dependent on each other (FP to the rescue). They should absolutely not block if you're going to write your code this way. If they are dependent and need to block they should be written this way: do_z(do_y(do_x())); Each one delivers a promise for it's computation. All you need is custom events and function decorators. Port my library Promises.js to Node.js ;) It's only about 300 LOC (another 5 or so to implement function decoration). http://github.com/ShiftSpace/promises http://github.com/ShiftSpace/promises
- xal 17y agoWhile not in the example that you replied to, it's assumed that you need the return value and want to do something with it. Think database query.
- tolmasky 17y agoprecisely, ideally this should just work: var result = do_x() + do_y(); and could. Again, if I understand the documentation for node.js correctly, simply automatically appending a .wait() to every promise returned should in theory give you this behavior (and be as performance/non-blocking/etc) as the other method.
- swannodette 17y agovar resultp = add(do_x(), do_y(); do_z(resultp); do_foo(); You're code will block on add. This code only blocks on unrealized promises, that is do_foo gets to execute. This is _more_ concurrent.
- tolmasky 17y agoYou're no longer arguing your original point, or at least, you're no longer arguing against me. Your code and my code are now nearly identical, except for the fact that you use an add function and I use an add operator. In fact, if I just say "my add operator can manipulate promises" or whatever, then they become 100% the same. Since my original point was that I'd like to use a preprocessor to make asynchronous programming as easy to transition to as possible, this would be very easy to achieve (just replace exp1 + exp2 with add(exp1, exp2)). That's what I meant by "just work", not "almost work". The goal was to not have to use callbacks and nesting, a point that both our code snippets have reached, so I'm not sure exactly what we're arguing about.