2014-08-27 124 views
0

我想用setTimeout递归调用几个函数。用setTimeout递归调用一个函数

var flag = 0 ; 
function slave1(){ 
    if(flag < 60) { 
     var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT1"); // Checking if DOM has loaded or not. If yes then doing something. 
     if (COPY_PO_LINE_DIV != null) { 
      flag = 0; 
      //doing something 
     } else { 
      setTimeout(slave1,2000); //waiting for 2 seconds and checking again. 
     } 
    } 
} 

//doing similar task 
function slave2(){ 
    if(flag < 60) { 
     var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT2");    
     if (COPY_PO_LINE_DIV != null) { 
      flag = 0; 
      //doing something 
     } else { 
      setTimeout(slave2,2000); 
     } 
    } 
} 

function master() { 
    slave1(); 
    console.log("Without completing slave1 function."); 
    slave2(); 
} 

通过master()功能我想打电话给多种功能此起彼伏,然而,在目前的情况下其调用slave2()没有完成slave1()。我如何确保slave1()已执行完成。如果没有加载DOM元素,则应该每2秒执行60次,并且应该从slave1()开始执行,然后转到下一个。

如果不加载dom元素而没有将控件返回到下一个函数,我想执行60次相同的函数。

+0

你使用任何JS库或者它必须是纯JS解释这个问题? – Tomalak 2014-08-27 11:44:20

+0

Pure JS .................... – 2014-08-27 13:49:15

回答

3

您需要调整slave1以在完成时运行回调,该回调将为slave2

function slave1(callback){ 
    if(flag < 60) { 
     var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT1"); // Checking if DOM has loaded or not. If yes then doing something. 
     if (COPY_PO_LINE_DIV != null) { 
      flag = 0; 
      //doing something 
      callback(); 
     } else { 
      setTimeout(slave1,2000); //waiting for 2 seconds and checking again. 
     } 
    } 
} 

function slave2(){...} 

function master() { 
    slave1(slave2); 
    console.log("Without completing slave1 function."); 
} 

这是您的基本JavaScript链接。如果您有更多的奴隶你可能想看看async.series否则你进入回调地狱中的Gabs00已经说得好听:

slave1(function(){ 
    slave2(function(){ 
     slave3(function(){ 
      slave4(slave5); 
     }); 
    }); 
}); 

如果需要值传递给回调,那么你需要使用一个中间匿名函数,该函数继而用所讨论的参数调用预期的回调。要做到这一点,你需要让他们使用的参数定义功能:(?如果有的话)

function slave1(str, callback){...} 
function slave3(i, callback){...} 

slave1("some argument", function(){ 
    slave2("another argument", function(){ 
     slave3(1, function(){ 
      slave4(2, slave5); 
     }); 
    }); 
}); 
+0

谢谢!有帮助......但假设我连续有5个功能,而不是如何从他们连锁。 – 2014-08-27 11:20:37

+1

@Mike那么你有效地输入回拨地狱,考虑承诺 – Gabs00 2014-08-27 11:23:55

+0

@ Artjom-如果我还必须通过几个参数? – 2014-08-27 13:54:21

0

slave2功能应该传递给slave1功能作为一个回调,并应在slave1它完成后调用。由于setTimeout()函数是异步的,因此您的当前情况非常普遍,因此JS解释器不会等待函数完成,而是会将Echloop循环结束时的setTimeout()结果设置为并继续处理master()方法。

1

考虑使用承诺这样的事情。这里是一个在jQuery之上的实现,其他许诺库的工作方式也是类似的。现在

function waitForElement(elementId, maxTries, checkInterval) { 
    var d = $.Deferred(), intvalID, checkFunc; 

    // set up default values 
    maxTries = maxTries || 60; 
    checkInterval = checkInterval || 2000; 

    checkFunc = function() { 
     var elem = document.getElementById(elementId); 
     if (maxTries-- > 0 && elem) { 
      clearInterval(intvalID); 
      d.resolve(elem); 
     } 
     if (maxTries <= 0) { 
      clearInterval(intvalID); 
      d.reject(elementId); 
     } 
    }; 

    // set up periodic check & do first check right-away 
    intvalID = setInterval(checkFunc, checkInterval); 
    checkFunc(); 

    return d.promise(); 
} 

,如果你想测试后的又一要素之一,可以级联这样的呼吁:

function master() { 
    waitForElement("DOM_ELEMENT1").done(function (elem1) { 
     waitForElement("DOM_ELEMENT2").done(function (elem2) { 
      alert("elem1 and elem2 exist!"); 
      // now do something with elem1 and elem2 
     }).fail(function() { 
      alert("elem1 exists, but elem2 was not found."); 
     }); 
    }).fail(function() { 
     alert("elem1 not found."); 
    }); 
} 

,或者你可以做到这一点并联有一个名为当所有的回调元素的存在:

function master() { 
    $.when(
     waitForElement("DOM_ELEMENT1"), 
     waitForElement("DOM_ELEMENT2") 
    ) 
    .done(function (elem1, elem2) { 
     alert("elem1 and elem2 exist!"); 
     // now do something with elem1 and elem2 
    }) 
    .fail(function() { 
     alert("not all elements were found before the timeout"); 
    }); 
} 
0

为了将参数传递给函数,创建匿名函数证明是一种矫枉过正。考虑使用“绑定”来代替。所以,如果你有

function slave1(str, callback){...} 
function slave2(str, callback){...} 
function slave3(i, callback){...} 
function slave4(i, callback){...} 
function slave5() 

而不是使用

slave1("some argument", function(){ 
    slave2("another argument", function(){ 
     slave3(1, function(){ 
      slave4(2, slave5); 
     }); 
    }); 
}); 

考虑的内存和CPU使用率方面使用

slave1("some argument", 
    slave2.bind(null, "another argument", 
     slave3.bind(null, 1, 
      slave4.bind(null, 2, slave5) 
     ) 
    ) 
); 

容易得多,更有效的。 现在,如何与setTimeout的做到这一点:

slave1("some argument", 
    setTimeout.bind(null, slave2.bind(null, "another argument", 
     setTimeout.bind(null, slave3.bind(null, 1, 
      setTimeout.bind(null, slave4.bind(null, 2, 
       setTimeout.bind(null, slave5, 0) 
      ),0) 
     ),0) 
    ),0) 
); 

我更详细的 http://morethanslightly.com/index.php/2014/09/executables-the-standard-solution-aka-mind-the-bind/