Javascript 控制台日志在setTimeout中出现意外延迟
下面的代码给出了一个意外的结果。它只等待1秒延迟(而不是delayBySeconds()函数指定的5秒),然后按如下所示打印输出Javascript 控制台日志在setTimeout中出现意外延迟,javascript,stack,settimeout,delay,eventqueue,Javascript,Stack,Settimeout,Delay,Eventqueue,下面的代码给出了一个意外的结果。它只等待1秒延迟(而不是delayBySeconds()函数指定的5秒),然后按如下所示打印输出 function func(){ const delaySeconds = 5; console.log("Alpha"); setTimeout(()=> {console.log("Beta");}, 1000); console.log("Gamma"); delayBy
function func(){
const delaySeconds = 5;
console.log("Alpha");
setTimeout(()=> {console.log("Beta");}, 1000);
console.log("Gamma");
delayBySeconds(delaySeconds);
console.log(`${delaySeconds} seconds passed`);
}
function delayBySeconds(sec){
let start = now = Date.now();
while((now - start) < (sec * 1000)){
//console.log(now);
now = Date.now();
}
}
func();
此外,如果在delayBySeconds()内重新激活console.log(现在),延迟将生效,否则“5秒已过”将在“Gamma”之后立即打印。
另一个意外的结果是,如果我在setTimeout()的参数中使用bare console.log(“Beta”),而不是()=>,那么“Beta”会在“Gamma”之前打印出来。有什么建议导致这种情况吗?这是否回答了您的问题?所有同步代码都将在任务队列被查看之前运行。您必须使
delayBySeconds
异步,才能按预期工作。至于正在打印的测试版,您将立即调用console.log
,而不是将其作为回调的主体传入function@ggorlen谢谢它澄清了一点(对我来说,这也是一个错误),即无论何时使用括号()编写函数名,即使将其传递给另一个函数,它都会立即调用它。这很清楚。但第二个问题是delayBySeconds函数显然不是异步的。为什么它不在while循环中继续读取和比较Date.now()时阻止执行5秒。它确实会阻止执行,从而阻止事件循环或渲染器运行。如果添加按钮,则在5秒钟的忙循环中,它无法响应单击。请参阅“delayBySeconds函数显然不是异步的”。。这是真的。。。它连续运行5秒,阻止其他任何东西运行。接下来要运行的是排队的同步代码(“已通过秒数”的日志),然后是默认情况下推送到事件循环末尾(在同步代码之后)的异步setTimeout
"Alpha"
"Gamma"
"5 seconds passed"
"Beta"