Asynconsistency
javascript |Because it is trivial to pass around functions in JavaScript, asynchronous programming comes easy. However, it’s equally easy to write code that results in unpredictable execution order.
For example, it wouldn’t be that odd to see a method like this on some object:
method: function(callback) {
if (this.condition) {
callback();
} else {
var client = new XMLHttpRequest();
client.open("GET", "http://example.com/", true);
client.onreadystatechange = function() {
if (client.readyState === 4) {
callback();
}
}
client.send(null);
}
}
With this method, the caller can’t be certain if the callback will be called before the return or after. Instead, this method should be written like this:
method: function(callback) {
if (this.condition) {
// always return before calling callback
setTimeout(callback, 0);
} else {
var client = new XMLHttpRequest();
client.open("GET", "http://example.com/", true);
client.onreadystatechange = function() {
if (client.readyState === 4) {
callback();
}
}
client.send(null);
}
}
This makes for predictable code flow, which is particularly important when a callback changes some shared state.
obj.method(changeEverything);
// I'm guaranteed that everything hasn't changed yet