javascript SetTimeout仅在函数退出时调用

javascript SetTimeout仅在函数退出时调用,javascript,asynchronous,web,Javascript,Asynchronous,Web,我注意到setTimeout(函数,毫秒) 当在函数中间使用时,只会在函数结束后执行,而不管给它什么时间 例如: 函数doStuff(){ var begin=(new Date()).getTime(); console.log(开始); setTimeout(函数(){console.log(“Timeout”);},100); 嫁妆(4000); var end=(新日期()).getTime(); 控制台日志(结束); log(“diff:”+(end-begin)); } 函数doW

我注意到
setTimeout(函数,毫秒)
当在函数中间使用时,只会在函数结束后执行,而不管给它什么时间

例如:

函数doStuff(){
var begin=(new Date()).getTime();
console.log(开始);
setTimeout(函数(){console.log(“Timeout”);},100);
嫁妆(4000);
var end=(新日期()).getTime();
控制台日志(结束);
log(“diff:”+(end-begin));
}
函数doWork(num){
对于(;num>0;--num)console.log(“num”);
}

doStuff()JavaScript不是先发制人的:它首先完成它正在做的事情,然后再查看队列中发布的下一个任务是什么(提交用于异步执行的函数)。因此,即使超时过期,也不会影响当前正在运行的代码——它不会被中断。只有当当前正在运行的函数堆栈已全部返回且没有任何内容需要运行时,JavaScript才会检查是否有超时请求需要完成,或者队列中的任何其他内容

发件人:

队列 JavaScript运行时包含一个消息队列,它是要处理的消息的列表。一个函数与每条消息相关联。当堆栈为空时,将从队列中取出一条消息并进行处理。处理包括调用相关函数(从而创建初始堆栈帧)。当堆栈再次变为空时,消息处理结束

事件循环 事件循环之所以得名,是因为它通常是如何实现的,它通常类似于:

while(queue.waitForMessage()){
  queue.processNextMessage();
}
queue.waitFormMessage
同步等待消息到达(如果当前没有消息)

“运行到完成” 在处理任何其他消息之前,每个消息都会被完全处理。在对程序进行推理时,这提供了一些很好的属性,包括这样一个事实:每当函数运行时,它都不能被抢占,并且将在任何其他代码运行之前完全运行(并且可以修改函数操作的数据)。这与C不同,例如,如果一个函数在一个线程中运行,它可以在任何时候停止以在另一个线程中运行其他代码

这种模式的一个缺点是,如果消息需要太长时间才能完成,web应用程序将无法处理诸如单击或滚动之类的用户交互。浏览器通过“脚本运行时间过长”对话框缓解此问题。要遵循的一个良好实践是缩短消息处理时间,如果可能,将一条消息缩减为多条消息


要使代码并发运行,可以使用。Web工作者在不同的线程中运行脚本。

因为javascript就是这样工作的。异步代码排队,并且在当前运行的代码完成之前执行。在浏览器中,您可以使用可以在隔离上下文中并发运行的命令。@t.niese当前运行代码的结尾是什么?当前作用域的结束?当前运行代码的结束是在调用堆栈为空时,即除了队列中等待的异步调用之外,没有其他东西可以运行。这是一次很好的演讲,深入探讨了这个话题。