2017-08-03 61 views
2

我有下面的功能,這是調用按鈕單擊,然後調用另一個函數內的定時器。爲什麼在最後調用回調函數以及如何測試函數?

下面是代碼:

<button id="starter">Start</button> 

JS:

document.getElementById ("starter").addEventListener ("click", myFunction, false); 

function myFunction() { 
    var start = new Date().getTime(); 
    console.log("Start", start); 
    d3.timer(() => { 
    var timepassed = new Date().getTime() - start; 
    console.log("Time elapsed", timepassed); 
    helloBlah(timepassed); 
    if(timepassed >= 200) return true; 
    }); 
    console.log(" Why am I triggered first rather than the timer?"); 
} 

function helloBlah(e){ 
    console.log("Hello Blah"); 
} 

這裏是JSFiddle

爲什麼d3計時器和裏面的函數晚於它下面的控制檯消息被調用?我如何在控制檯消息之前調用它,以及如何在Jasmine中爲這些類型的函數編寫測試?

+2

定時器是異步和JavaScript是單線程的。這意味着回調將不會被調用,直到時間到,並且當前正在運行的線程完成。 – 4castle

回答

3

這是預期的行爲。

D3定時器不同於setTimeoutsetInterval:除了別的以外,它們在頁面背景停止時停止。

然而,就像當你使用一個setTimeout 0毫秒發生什麼事,你看到的行爲是由事實來解釋設置最小延遲並不意味着該功能將被執行立即:它只是意味着它將在當前正在執行的代碼完成後立即執行。

我們可以使用d3.timeout(不存在於v3中,僅在v4中)顯示此內容,這與d3.timer僅被調用一次不同。看一看控制檯:

d3.select("button").on("click", function() { 
 
    d3.timeout(function() { 
 
    console.log("I'm inside d3.timeout, I should come first!") 
 
    }); 
 
    console.log("I'm outside d3.timeout and after it") 
 
    console.log("I'm outside d3.timeout and after it too") 
 
})
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<button>Click Me</button>

+1

關於其他兩個問題,請每個帖子只保留**一個問題**。每個帖子詢問多個問題是Stack Overflow關閉的理由。 –

+0

會記住這一點:)解釋幫助了很多。乾杯。 – zelda

相關問題