2014-08-27 137 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/