I am aware that I'm kicking a potentially angry beehive by bringing up this topic, but I wanted to just have some discussion around if there's any possibility that JavaScript can, in the near term, have a native mechanism added to it for better managing of sync vs. async coding patterns, without nested callbacks.
The more formalized approach to this topic is typically labeled "promises" (and/or "defers"). While what I'm going to propose is going to borrow some language and ideas from that crowd, let me just say: *I am not qualified as anything remotely like proficient in all the ins and outs of promises/defers*. I am just a JavaScript developer who's trying to boil the formalized stuff down into some simpler ideas, and explore ways that JavaScript could natively be enhanced with building blocks to address those issues. I will not bog down this email thread with a detailed description of all the problems with callbacks, but I encourage you to read the first half of my most recent blog post, as I go into much detail about those issues there. http://blog.getify.com/2010/12/native-javascript-sync-async It's *not* just a question of syntactic sugar -- I believe there's a fundamental paradigm with callbacks that is deficient, and actually *that* is my primary motivator. Where my proposal will have possibly shorter/simpler syntax, i consider that a benefit, but not the primary motivator. Moreover, I don't necessarily want to stoke the flames of syntactic perferences. I'd rather discuss some underlying basic pieces of the puzzle. Also, Brendan suggested exactly the same -- that we start with discussion of the semantics and exeuction model, rather than syntax. My proposal (semantics/processing model first, syntax second) is located in the second half of that post, here: http://blog.getify.com/2010/12/native-javascript-sync-async/#proposal Briefly, in summary, I'm suggesting a statement like this in JavaScript: ???? X(1,2) ???? Y(3,4) ???? Z("foo") ????; `X`, `Y`, and `Z` are all possibly function calls which will not complete synchronously, but may defer their fulfillment asynchronously until a later time/event. The spirit of the proposal is that this special type of statement be a linear sequence of function executions (as opposed to nested function-reference callbacks delegating execution to other code). The special behavior is that in between each part/expression of the statement, evaluation of the statement itself (NOT the rest of the program) may be "suspended" until the previous part/expression is fulfilled. This would conceptually be like a yield/continuation localized to ONLY the statement in question, not affecting the linear execution of the rest of the program. The model for the suspension and resuming of such evaluation would be, under the covers, identical (as much as possible) to how async callbacks are deferred to execute until a later time (turn based, etc). Any regular statement that appears after this special type of statement would be evaluated/executed as soon as either the statement in question completes (if all parts are in fact synchronous and not-deferred), or as soon as some part of the statement in question defers, to "suspend" evaluation of the rest of the statement. There are other details to the proposed mechanism, including "message passing" between each step in the sequence of expressions in the statement, and also conditional execution, for allowing both a "success" and "failure" path to be defined. "Success" path would be taken if the deferred/suspended expression fulfills itself under expected conditions, and "Failure" path otherwise. The mechanism would ensure that only one of either the "success" or "failure" paths was taken for any particular deferral/suspension upon resuming. Lastly, no special behavior with respect to the state of surrounding variables/scope is implied during the resumed-from-suspension execution of the statement. Normal scoping/closure rules would apply, meaning the current state at time of resume would be respected. ------------ I'm not trying to solve all of the possible issues/use-cases with dealing with complex async/chained logic through promises/defers. I'm not suggesting that noone will ever have to use a promise/defer "lib" of some sort again for the more complex negotiation tasks. I'm not suggesting that my proposal will be the cure all. What I am suggesting is that the best first step to take in helping deal with sync/async negotiation in JavaScript is for there to be a small, narrowly defined, natively implemented mechanism, which will serve as a building block for more complex usage, and will simultaneously provide very streamlined and simple syntax for a wide array of common sync/async tasks (like event binding, etc). I welcome any thoughts/feedback on the viability of such a proposal, or pitfalls or structural shortcomings I may not have forseen yet. But again, let's not get mixed up in the weeds of syntax preference just yet. Thanks, Kyle (aka @getify)
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss