These days I write JavaScript using only functions, literals, variables, and the occasional prototype and it's amazing.
I think many programmers have a desire to believe they are working on complex problems that demand sophisticated tools. I remember learning Ruby and being excited whenever I found a reason to write a DSL. In retrospect it was unnecessary every time. In every case the code would've been clearer if I had just stuck with functions and kept refactoring until I had the right interfaces and data structures.
It helps to remember
function a() {
b(function() {
//etc
})
}
is equivalent to function a() {
b(c)
}
function c() {
//etc
}
which is not particularly more verbose. And as a side benefit, refactoring that way gives you an opportunity to make c() self-documenting.> function a() { b(function() { //etc }) } is equivalent to
> function a() { b(c) } function c() { //etc } which is not particularly more verbose. And as a side benefit, refactoring that way gives you an opportunity to make c() self-documenting.
It's not always equivalent, since you can have closures.
In some sense closures are globals and globals are bad.
var fs = require('fs');
var async = require('async');
async.waterfall([
(cb) => fs.readFile('foo.txt', cb),
(data, cb) => my_function(data, cb),
(result, cb) => myDb.lookup(result, cb),
], (err, finalResult) {
if (err) {
console.error(err);
} else {
console.log(finalResult);
}
});
There are all sorts of helpful async primitives in there. I don't write Javascript without it!Here is a link to the documentation: https://github.com/caolan/async
If you're trying to convince me that "callbacks become painful in situation X" you really don't need to. I know that. What I'm saying is that 9 times out of 10, the answer to the question "do we really want to be in situation X in the first place?" is "no". But instead of getting out of a bad situation by refactoring, people just write crazier and crazier control structures (i.e. promises) to make those bad situations workable.
https://nodejs.org/api/domain.html
But it was deprecated: https://github.com/nodejs/node/issues/66
promises are a very nice way of drying out error handling and cleaning up callbacks for now.
Chrome has support for debugging async code - for example you can step from one code block to the code in callback as if it would be executed sequentially. So the 'debuggability' is a problem which could be solved on the side of the tools. Of course the case where there would be one single standard for handling async would vastly simplify situation for the tools developers.
It is not common to have "readability" in CoffeeScript and it restricts a significant number of readers from being able to understand the code sample.
Can you seriously say you can't read it? It seemed easy to me.
That's a control flow solution I wrote on top of generators to make it a little easier to manage parallel tasks, timeouts, error handling, and so on.
I originally made asyncblock, which was based on fibers a few years ago. This module uses the same underpinnings as asyncblock, just based in generators instead of fibers.
This makes it impossible, for instance, to write a nice I/O library that is to be called from within a generator (the library is supposed to yield on a blocking situation).