函数nodejs中的async map,recursion和callback的组合

时间:2017-01-06 13:20:02

标签: javascript node.js asynchronous recursion callback

我有一个计算值的函数,并在计算返回值后回调另一个函数。

在我有2个嵌套for循环和递归的情况下,情况开始变得相当混乱。

错误是:uncaughtException: Callback was already called.

首先让我编写代码示例。

functionTest (array, function (err, result) {
  if (err) {
    nresponse.error(err);
  } else {
    nresponse.success(res, result);
  }
);

function dependicies(array, callback) {
    async.map(array, function(item, outerNext) {
        async.map(item.members, function(value, innerNext){
            dependicies(array, callback);
            innerNext(); //should I write this after or before the recursion call?
            outerNext(); //where should I call the outerNext?
        });

    }, function(err, result){
        **
        if(err){
            callback(err); 
        }else{
            callback(null, sthComputedInMap);
        }
    });
}

正如我在评论中写的那样,我应该在递归调用之后或之前编写innerNext吗?除了这个问题,我应该在第二张地图的范围之后调用outerNext吗?

事情很糟糕。我该如何清理?我正在看文件。

**这不是第一个async.map结束的地方。我认为问题在于each的{​​{1}} async.map。我想要的是将其称为recursion

在代码中我尝试循环遍历数组。假设我尝试获取一个文档的名称字段列表,从自己开始到最后一个盛大的孩子。我追踪的阵列结构是这样的;

break

首先,async.map用于遍历每个文档,另一个用于遍历其子数组。

我希望它有所帮助:)

2 个答案:

答案 0 :(得分:0)

基于我对您在问题中提供的内容的理解。您的递归呼叫不在正确的位置。解决问题的一种方法是:

function dependencies(array, callback){
  outerResult = async.map(array, function(item, outerNext){
    var innerResult = async.map(item.members, function(value, innerNext){
     //recursive_call_condition == true
     // for instance you want to check if value has an array further
     if(value.members.length) 
         dependencies(value.members, callback);
     else
         innerNext(null, innerResult);
    });
    outerNext(null, outerResult);
  }, function(err, finalResult){
     // `finalResult` is your result
     callback(finalResult)
  });
}

答案 1 :(得分:0)

您可以使用SynJS混合循环,递归和回调。下面是一个工作示例来说明。 setTimeout仅用作通过回调返回结果的异步函数的示例。

global.SynJS = global.SynJS || require('synjs');

function processOneDoc(modules, documents, doc, childNames) {
    for(var i=0; doc.childrenIds && i < doc.childrenIds.length; i++) {
        var currDoc = documents[doc.childrenIds[i]];
        if(currDoc) {
            childNames.push(currDoc.name);
            var chNames=[];
            setTimeout(function(){
                SynJS.run(modules.processOneDoc, null, modules, documents, currDoc, chNames, function(){
                    SynJS.resume(_synjsContext);
                });
                if(chNames.length)
                    childNames.push(chNames);
            },2000);
            SynJS.wait();
        }
    }
};

function processAll(modules, documents) {
    for(var d in documents) {
        var childNames=[];
        SynJS.run(modules.processOneDoc,null, modules, documents, documents[d], childNames,function(){
            SynJS.resume(_synjsContext);
        });
        SynJS.wait();
        console.log(new Date().toISOString(), d, childNames);
    }
}

var modules = {
        SynJS:  SynJS,
        processOneDoc: processOneDoc,
};

var documents = {
                 1: {id: 1, childrenIds: [3, 4, 5], name: "name of 1st"},
                 3: {id: 3, childrenIds: [8, 5], name: "name of 3rd"},
                 21: {id: 21, childrenIds: [ 5], name: "name of 21st"},
                 7: {id: 7, childrenIds: [5], name: "name of 7th"},
                 5: {id: 5, childrenIds: [], name: "name of 5th"}
};

SynJS.run(processAll,null,modules,documents,function () {
    console.log('done');
});

它会产生以下输出:

2017-01-06T18:50:57.750Z 1 [ 'name of 3rd', [ 'name of 5th' ], 'name of 5th' ]
2017-01-06T18:50:59.785Z 3 [ 'name of 5th' ]
2017-01-06T18:50:59.800Z 5 []
2017-01-06T18:51:01.831Z 7 [ 'name of 5th' ]
2017-01-06T18:51:03.863Z 21 [ 'name of 5th' ]
done