使用 async.js 的异步树遍历

Posted

技术标签:

【中文标题】使用 async.js 的异步树遍历【英文标题】:Asynchronous tree traversal using async.js 【发布时间】:2016-01-06 20:45:24 【问题描述】:

我正在尝试使用 async.js 遍历嵌套项目树。遍历仅经过一个分支后终止。

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;
            
        
    );
;

【问题讨论】:

=+ 不是 javascript 加法赋值运算符。 . . 你是不是刚刚从那个错误中得到了运行时错误? 【参考方案1】:

逻辑有点复杂,所以我先确保没问题。以下是您可能错过的几件事。计数+= 就像前面提到的。您的迭代器中没有回调,而且您还在extendedFamily.kids 中推动家庭两次。

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】:

我误解了callback()async.js 库中的使用。这篇文章帮助我理解了:http://www.sebastianseilund.com/nodejs-async-in-practice 这是我的解决方案:

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)
        
    );

【讨论】:

以上是关于使用 async.js 的异步树遍历的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript的sleep实现--Javascript异步编程学习

JS 的异步遍历,你真的会写吗?

多级树的深度优先遍历与广度优先遍历(Java实现)

树和森林的遍历

二叉树遍历之非递归算法

Array中使用异步函数遍历元素