-->

Asynchronous tree traversal using async.js

2019-06-17 08:33发布

问题:

I'm trying to traverse a tree of nested of items using async.js. The traversal terminates after going through just one branch.

var count=0;
exports.buildFamily = function(item_id, mback){
    var extendedFamily={};

    exports.getItembyId(item_id, function(err, item){
        extendedFamily=item;
        if(item.descendants){
            extendedFamily.kids=[];
            count=+item.descendants.length;
            console.log('outercount ' + count);
            async.eachSeries(item.descendants, function(item){                
                count--
                console.log('item: ' + item)
                exports.buildFamily(item, function(err, family){
                    console.log('deepcount: ' + count);
                    extendedFamily.kids.push(family);
                    if(count===0){ return mback(null, extendedFamily);}
                    else {extendedFamily.kids.push(family);}
                })
           })

        }
        else{
            if(count===0){ return mback(null, extendedFamily);}
            else{
                extendedFamily.kids.push(family);
                return;
            }
        }
    });
};

回答1:

The logic is quite a bit convoluted so I'd make sure that's fine first. Here's a few things that you probably missed. count += like previously mentioned. No callback inside your iterator and you were also pushing family inside extendedFamily.kids twice.

count += item.descendants.length;
console.log('outercount ' + count);
async.eachSeries(item.descendants, function(item, cb) {                
    count--;
    console.log('item: ' + item);
    exports.buildFamily(item, function(err, family){
        console.log('deepcount: ' + count);
        if(count===0){ return mback(null, extendedFamily);}
        else {
             extendedFamily.kids.push(family);
             cb();
        }
    })
})


回答2:

I misunderstood the use of the callback() in the async.js library. This article helped me get an understanding: http://www.sebastianseilund.com/nodejs-async-in-practice This was my solution:

exports.buildFamily = function(item_id, done){
    console.log('API:buildFamily');

    var extendedFamily={}
    exports.getItembyId(item_id, function(err, item){
        if(err){throw err}
        extendedFamily=item;
        if(item.descendants){
            extendedFamily.kids=[]
            async.eachSeries(item.descendants, function(item_id, callback){
                exports.getItembyId(item_id, function(err, item){
                    if(err){throw err}
                    if(item.descendants){
                        exports.buildFamily(item.item_id, function(err, family){
                            extendedFamily.kids.push(family);
                            callback();
                        })
                    }else{
                        extendedFamily.kids.push(item);
                        callback();
                    }                            
                })
            }, function(err){
                done(null, extendedFamily)
            })

        }else{
            done(null, extendedFamily)
        }
    });
}