2017-08-03 87 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

相关问题