I hear this over and over again but I frankly do not get it. I write JavaScript every day and got over the nested callback problem ages ago. I don't say this to refute the point; I legitimately don't get it and feel like maybe I'm doing something wrong because I don't encounter the problem. Here's how I write stuff that requires several callbacks:
function TakesAWhile() {
}
TakesAWhile.prototype = {
start: function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'api/foo', true);
xhr.onreadystatechange = this.posted.bind(this);
xhr.send('bar');
},
posted: function(e) {
if(!(e.target.readyState !== 4)) {
this.complete('error :-(');
return;
}
db.saveSomething(someObject, this.saved.bind(this));
},
saved: function(e) {
db.getFreshCopy('foo', this.got.bind(this));
},
got: function(e) {
var foo = e.target.result;
this.complete(foo);
}
};
Then I consume it like this: var stuff = new TakesAWhile();
stuff.complete = function(foo) {
console.log('All complete!');
};
stuff.start();I hear you. Have you heard of iced coffee script ?(http://maxtaco.github.com/coffee-script/) I didn't sleep well the night after I read that.
.
follow = (from, to, cb) ->
# Invokes four async operations in a series, which requires 4 `await`, `defer`
# using iced. Note how error handling is handled
# in one place rather than each step.
# That's a big drawback for me with await/defer.
async.series
user: (cb) -> User.find name:from, cb
addFollowing: (cb, results) ->
results.user.following.push to
User.save results.user, cb
followee: (cb) ->
User.find name:to, cb
addFollower: (cb, results) ->
results.followee.followers.push from
User.update results.followee, cb
, (err, results)
cb err, resultsI feel exactly the same as you: Javascript, as a language, just does nothing to help you. You've done a better elucidation of it than I could, I just always felt JS was being unhelpful; be it getting the value of an object, be it the inheritance syntax (I have no issues with the prototypal aspect, just the way you express it), lack of good ways to move through a list, the somewhat difficult to understand scoping of 'this'...
It's not that any one thing is especially broken, it's just that all added up I feel like it's not finished, and I'm not Getting Stuff Done as I do with Python.
Google Closure seems to go some of the way there, but I get the feeling that's probably just adding some syntactic sugar to make swallowing the bitterness a bit easier.
The explosion of the web opened the doors to new languages after a long stagnation of client-side code. Why let an accident of browser development history dictate the tools we use for the next 5-10 years?
JavaScript is also getting the ability to change property lookup behavior on objects using Proxy (available since Firefox 4).
Browsers are moving faster, which helps here... and for people using Node, you can use these features as soon as Node gets them.
I miss a set type, I miss solid iteration (although coffescript mitigates that), and immutable datatypes would be nice (I've got used to them in Clojure.) I miss a solid FP stdlib, although jQuery has map and filter, which goes a long way.
That's the ones I can immediately think of :).