2012-05-24 95 views
3

在所有代碼運行之前完成一項功能的噩夢。我試圖建立一個計數器,並且只在代碼完成時才返回。Javascript循環 - 等待值

我模擬了這款像這樣(我知道這不是美妙的,但如果有人能沿着正確的線路指向我,我會非常感激):

//I want this to alert "Done" 
alert(timerCheck()); 

function timerCheck() { 
    var finished; 
    var myLoop = 5; 
    for (i = 0; i < myLoop; i++) { 
        //This is emulating the slow code 
        window.setTimeout(checkFinished, 900); 
        alert(i); 
    } 
    function checkFinished() { 
        //I originally had the "return here, before realising my error 
        finished = true; 
    } 
    if (finished) { 
        //This is where my problem is  
        return "done"; 
    } 
} 

就像我說的,更簡單的例子 - 如果有人能指出這個錯誤,它會爲我節省很多麻煩!

+5

如果該函數調用並取決於異步函數,則無法同步獲取函數的返回值。你必須使用回調。見http://stackoverflow.com/questions/2070275/javascript-closures-and-callbacks –

+0

如果你有權訪問jquery,你可以使用deferred和promise:http://stackoverflow.com/questions/5009194/how-to -use-jquery-deferred-with-custom-events – jbabey

回答

4

如果函數調用並取決於異步函數,則無法同步獲取函數的返回值。

你必須使用回調。有關更多詳細信息,請參閱this question

例如,你的函數應該是這樣的:

// pass a callback which gets the result of function 
timerCheck(function(result) { 
    alert(result); 
}); 

function timerCheck(callback) { 
    var myLoop = 5, 
     j = 0; 

    for (var i = 0; i < myLoop; i++) { 
     // This is emulating the slow code 
     // this will invoke `checkFinished` immediately, 
     // after 900ms, after 1800ms, after 2700ms and after 3600ms 
     window.setTimeout(checkFinished, i * 900); 
    } 

    function checkFinished() { 
     j++; 
     // after checkFinish was called 5 times, we invoke the callback 
     if(j === 5) { 
      callback('done'); 
     } 
    } 
} 
+0

當然!謝謝! – Richard

+0

你救了我的命:)) – Machete

-3

你有沒有嘗試過沒有parens後函數名?

alert(timerCheck); 
+2

這隻會提醒函數的正文,而不是調用函數。 –

0

由於FelixKling評論,你不能得到一個函數的返回值同步如果函數調用和依賴於異步函數。這些樣的工作的一個解決辦法是:

var finished = false; 

function mySlowCode() { 
    setTimeout(function() { 
     finished = true; 
    }, 1000); 
} 

function timerCheck() { 
    // legend... 
    (function waitForIt() { 
     setTimeout(function() { 
      if (!finished) { 
       waitForIt(); 
      } else { 
       // dary! 
       letsDoIt(); 
      } 
     }, 10); 
    })(); 
} 

function letsDoIt() { 
    alert("done"); 
} 

mySlowCode(); 
timerCheck(); 

功能timerCheck()會調用該函數letsDoIt()一旦功能mySlowCode()完成。