0

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

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

顺便说一句,真正的代码位于单独的隔离网络上,因此无法直接剪切和粘贴到此处。下面是相关部分的功能等效(除非我打错了)。对此表示歉意。任何帮助,将不胜感激。

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 
4

1 回答 1

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

如果您确实需要异步执行,则实现将取决于您使用的异步机制(网络工作者、使用 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);
           }
       }
   );
}
于 2013-07-18T18:22:13.647 回答