递归函数在递归调用完成之前完成

时间:2013-07-18 18:05:22

标签: javascript recursion closures anonymous-function

我是javascript的新手,并不具备异步方面,闭包等方面的能力。我已经对此进行了几天的研究以及大量的试用和试用。错误,但似乎无法解决我的问题,这是:

我正在尝试走树结构,收集所有底层节点(没有子节点的节点)。此节点数据将加载到全局数组中(不是最佳但需要)。我正在使用的walk函数是递归的。但是异步性质导致在递归调用返回之前对函数的第一次调用返回,因此完整的树不会被询问。我尝试将它放在一个匿名函数中,似乎遍历整个树,但是全局数组没有被加载(不可访问?)。

BTW,真正的代码是在一个单独的,孤立的网络上,所以直接切割&粘到这里是不可能的。以下是相关部分的功能等同物(除非我做了拼写错误)。为此道歉。任何帮助将不胜感激。

var nodeList = new Array(); // global variable

function someFunction(rootNode) {
   // unrelated processing here
   walkTree(rootNode);   // gather the childless nodes
   return;
}

function walkTree(node) {
   return function() {   // required in order traverse the entire tree
                         // but with it, nodeList does not get populated
      var num = node.numChildren();
      var childNodes = node.getChildNodes();
      for (var i=0; i<num; i++)  {
         var currentNode = childNodes.item(i);
         if (currentNode.numChildren() > 0) {
            walkTree(currentNode);
         }
         else {
             var obj = new Object();
             /// extract certain attributes of current node here
             /// and make a variant 
             nodeList[nodeList.length] = obj;
         }
      } // END for
   } // close anonymous function
} // END FUNCTION 

1 个答案:

答案 0 :(得分:0)

如果您不需要异步执行,可以简化代码:

var nodeList = [];

function someFunction(rootNode) {
   // unrelated processing here
   walkTree(rootNode);   // gather the childless nodes
   return;
}

function walkTree(node) {
   var num = node.numChildren(),
       childNodes = node.getChildNodes();
   for (var i=0; i<num; i++)  {
      var currentNode = childNodes.item(i);
      if (currentNode.numChildren() > 0) {
         walkTree(currentNode);
      }
      else {
         var obj = new Object();
         /// extract certain attributes of current node here
         /// and make a variant 
         nodeList.push(obj);
      }
   }
}

如果确实需要异步执行,那么实现将取决于您使用的异步机制(Web worker,使用setTimeout进行模拟,使用Clumpy等框架)。

例如,对于Clumpy,您可以像这样(未经测试)编写代码:

var nodeList = [],
    clumpy = new Clumpy();

function someFunction(rootNode) {
   // unrelated processing here
   walkTree(rootNode);   // gather the childless nodes
   return;
}

function walkTree(node) {
   var num = node.numChildren(),
       childNodes = node.getChildNodes(),
       i;
   clumpy.for_loop(
       function() { i = 0; },
       function() { return i < num; },
       function() { i++; },
       function() {
           var currentNode = childNodes.item(i);
           if (currentNode.numChildren() > 0) {
              walkTree(currentNode);
           }
           else {
              var obj = new Object();
              /// extract certain attributes of current node here
              /// and make a variant 
              nodeList.push(obj);
           }
       }
   );
}