Javascript SetTimeout未返回正确的值和无响应的脚本

Javascript SetTimeout未返回正确的值和无响应的脚本,javascript,jquery,firefox,settimeout,Javascript,Jquery,Firefox,Settimeout,假设我想将一个元素的所有后代标记名放入一个数组中 var node = document.getElementById('mainbar'); 但是,由于我们使用下面的函数在多个节点之间循环,因此我添加了一个setTimeout函数,以便在每50次循环之后对函数进行超时 function MyFunction(root){ "use strict"; var myarray = [], descendants, descendant, i=1, l; descend

假设我想将一个元素的所有后代标记名放入一个数组中

var node = document.getElementById('mainbar');
但是,由于我们使用下面的函数在多个节点之间循环,因此我添加了一个setTimeout函数,以便在每50次循环之后对函数进行超时

function MyFunction(root){
    "use strict";
     var myarray = [], descendants, descendant, i=1, l;
     descendants = root.getElementsByTagName('*');

     function getParentNode(){
        for(l = descendants.length; i<l ; i++){
          descendant = descendants[i];
          myarray.push({ tagName: descendant.tagName});

         //  After 50 loops, increment i, setTimeout
          if(i % 50 == 0 ) {
            i++;
            setTimeout(getParentNode, 20);
          }

        }
     }

     function init(){
       getParentNode();
       return   JSON.stringify({ nodes:myarray });
     }

      return init();    
   }
函数MyFunction(根){
“严格使用”;
var myarray=[],子代,子代,i=1,l;
后代=root.getElementsByTagName('*');
函数getParentNode(){

对于(l=subjects.length;i,这里有几个问题:

  • 您仍然希望在
    init
    中调用
    getParentNode
    后,您的结果会出现在下一行。不会的。它还没有生成

  • 基本上与之相同:
    MyFunction
    返回
    init
    的结果将不起作用,因为
    init
    调度异步处理并在完成之前返回

  • getParentNode
    中,您正在为
    子体
    列表中的每个节点循环并安排对
    getParentNode
    new调用。您没有异步处理它们,而是一次安排了大量回调

  • getElementsByTagName
    返回的列表从
    1
    开始,而不是
    0

  • 如果这需要是异步的,则需要重构
    getParentNode
    来处理每个调用的一个元素

    但是,即使是嵌套非常深的结构,您也不太可能需要异步执行此操作,即使是在大型文档上,也不应该花费那么长的时间:

    function MyFunction(root) {
        "use strict";
        var myarray,
            descendants,
            i,
            l;
    
        descendants = root.getElementsByTagName('*');
        myarray = [];
        for (i = 0, l = descendants.length; i < l; i++) {
            myarray.push({
                tagName: descendants[i].tagName
            });
        }
    
        return JSON.stringify(myarray);
    }
    
    函数MyFunction(根){
    “严格使用”;
    var myarray,
    后代,
    我
    L
    后代=root.getElementsByTagName('*');
    myarray=[];
    对于(i=0,l=1.length;i
    这里有几个问题:

  • 您仍然希望在
    init
    中调用
    getParentNode
    后,您的结果会出现在下一行。不会的。它还没有生成

  • 基本上与之相同:
    MyFunction
    返回
    init
    的结果将不起作用,因为
    init
    调度异步处理并在完成之前返回

  • getParentNode
    中,您正在为
    子体
    列表中的每个节点循环并安排对
    getParentNode
    new调用。您没有异步处理它们,而是一次安排了大量回调

  • getElementsByTagName
    返回的列表从
    1
    开始,而不是
    0

  • 如果这需要是异步的,则需要重构
    getParentNode
    来处理每个调用的一个元素

    但是,即使是嵌套非常深的结构,您也不太可能需要异步执行此操作,即使是在大型文档上,也不应该花费那么长的时间:

    function MyFunction(root) {
        "use strict";
        var myarray,
            descendants,
            i,
            l;
    
        descendants = root.getElementsByTagName('*');
        myarray = [];
        for (i = 0, l = descendants.length; i < l; i++) {
            myarray.push({
                tagName: descendants[i].tagName
            });
        }
    
        return JSON.stringify(myarray);
    }
    
    函数MyFunction(根){
    “严格使用”;
    var myarray,
    后代,
    我
    L
    后代=root.getElementsByTagName('*');
    myarray=[];
    对于(i=0,l=1.length;i
    忽略其他人提到的所有其他问题,只回答如何实现异步功能的问题。您可以在代码中引入回调的概念。而不是在调用后立即尝试使用结果,而是在结果就绪后传递要调用的函数:

    函数MyFunction(根,回调){
    /* ... */
    函数getParentNode(){
    对于(l=l.length;i
    忽略其他人提到的所有其他问题,只回答如何实现异步功能的问题。您可以在代码中引入回调的概念。而不是在调用后立即尝试使用结果,而是在结果就绪后传递要调用的函数:

    函数MyFunction(根,回调){
    /* ... */
    函数getParentNode(){
    对于(l=l.length;i
    如果使用的是
    设置超时
    ,则无法同步返回result@David我正在setTimeout中调用getParentnode()。您是否询问了其他问题?您的注释是“并中断函数”,但您没有这样做。另外,
    if(I%50){…}
    不会只运行每个第50个循环,它会运行每个循环,除了第50个循环的倍数。你需要
    如果(!(i%50)){…}
    hmm…那不是做了与你想做的相反的事情吗?
    1%50=1
    所以在第一个站点上