Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Callbacks are more and more a requirement in coding, especially when you think about Node.JS non-blocking style of working. But writing a lot of coroutine callbacks quickly becomes difficult to read back.

For example, imagine something like this Pyramid Of Doom:

// This asynchronous coding style is really annoying. Anyone invented a better way yet?
// Count, remove, re-count (verify) and log.
col.count(quertFilter,          function(err, countFiltered) {
    col.count(queryCached,      function(err, countCached) {
        col.remove(query,       function(err) {
            col.count(queryAll, function(err, countTotal) {
                util.log(util.format('MongoDB cleanup: %d filtered and %d cached records removed. %d last-minute records left.', countFiltered, countCached, countTotal));
            });
        });
    });
});

is something we see often and can easily become more complex.

When every function is at least a couple of lines longer, it starts to become feasible to separate the functions:

// Imagine something more complex

function mary(data, pictures) {
    // Do something drastic
}

// I want to do mary(), but I need to write how before actually starting.

function nana(callback, cbFinal) {
    // Get stuff from database or something
    callback(nene, cbFinal, data);
}

function nene(callback, cbFinal, data) {
    // Do stuff with data
    callback(nini, cbFinal, data);
}

function nini(callback, data) {
    // Look up pictures of Jeff Atwood
    callback(data, pictures);
}

// I start here, so this story doesn't read like a book even if it's quite straightforward.

nana(nene, mary);

But there is a lot of passing vars around happening all the time. With other functions written in between, this becomes hard to read. The functions itself might be too insignificant on their own to justify giving them their own file.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
523 views
Welcome To Ask or Share your Answers For Others

1 Answer

Use an async flow control library like async. It provides a clean way to structure code that requires multiple async calls while maintaining whatever dependency is present between them (if any).

In your example, you'd do something like this:

async.series([
    function(callback) { col.count(queryFilter, callback); },
    function(callback) { col.count(queryCached, callback); },
    function(callback) { col.remove(query, callback); },
    function(callback) { col.count(queryAll, callback); }
], function (err, results) {
    if (!err) {
        util.log(util.format('MongoDB cleanup: %d filtered and %d cached records removed. %d last-minute records left.', 
            results[0], results[1], results[3]));
    }  
});

This would execute each of the functions in series; once the first one calls its callback the second one is invoked, and so on. But you can also use parallel or waterfall or whatever flow matches the flow you're looking for. I find it's much cleaner than using promises.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...