首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >setInterval和setTimeout是如何工作的?

setInterval和setTimeout是如何工作的?
EN

Stack Overflow用户
提问于 2014-02-26 19:24:40
回答 5查看 31.4K关注 0票数 37

I 当时处境很尴尬,

我在纯JavaScript上工作了近3年,我知道JavaScript是单线程语言,您可以使用setIntervalsetTimeout函数模拟异步执行,

但是当我想到他们怎么工作的时候,我就不明白了。那么这些函数是如何影响执行上下文的呢?

我想,在特定的时间里,代码只运行一部分,然后切换到另一部分。如果是这样,那么许多setIntervalsetTimeout调用会影响性能吗?

EN

回答 5

Stack Overflow用户

发布于 2015-04-01 13:04:57

Javascript是单线程的,但浏览器不是。浏览器至少有三个线程: Javascript线程、UI线程和计时线程,其中setTimeoutsetInterval的定时由计时线程完成。

当调用setTimeoutsetInterval时,浏览器中的计时器线程开始计数,当时间增加时,将回调函数放入javascript线程的执行堆栈中。在堆栈上的其他函数完成之前,不执行回调函数。因此,如果在超时时执行其他耗时的函数,则setTimeout的回调不会及时完成。

票数 50
EN

Stack Overflow用户

发布于 2017-12-01 10:26:44

setTimeout / setInterval如何在JavaScript中工作

浏览器有用于计时器功能的API,就像用于事件ex的API一样。

‘点击’‘滚动’

假设您的应用程序中有以下代码

代码语言:javascript
复制
function listener(){
    ...
}

setTimeout(listener, 300)

function foo(){
    for(var i = 0; i < 10000; i++){
        console.log(i)
    }
}

foo()

1:https://i.stack.imgur.com/j6M6b.png

在这一点上,正如我们在上面编写的代码一样,我们的调用堆栈看起来如下

调用堆栈-> foo

让我们假设foo需要1s来完成它的执行,因为我们已经在代码中定义了一个超时,并且在"foo“完成它的执行之前我们正在运行它,也就是说,在300‘s处

然后会发生什么呢?

javascript是否停止执行foo并开始执行setTimeout?

No

我们已经知道javascript是单线程的,所以它必须在前进之前完成foo的执行,但是浏览器如何确保foo执行后"setTimeout“会执行呢?

这里,javascript魔术出现在图片中。

当300 is过期时,浏览器的"Timer API“启动并将超时处理程序放入”消息队列“。

此时,上面图像中的“消息队列”如下所示

消息队列-> setTimout:

调用堆栈-> foo

当“调用堆栈”变为空时,也就是说foo完成了它的执行,如图中所示的“事件循环”将从消息队列中获取消息并将其推到堆栈中

“事件循环”的唯一工作是“调用堆栈”变为空,“消息队列”中有条目,然后将消息表单“消息队列”排出队列,并将其推入“调用堆栈”。

此时,上面图像中的消息队列将如

消息队列->

调用堆栈->侦听器

这就是setTimeout和setInterval的工作方式,尽管我们在setTimeout中指定了300 ms,它将在"foo“完成它的执行之后执行,在本例中,即在1之后执行。这就是为什么在setTimeout/setInterval中指定的计时器指示执行函数的“最小时间”延迟。

票数 18
EN

Stack Overflow用户

发布于 2018-10-07 07:18:43

Javascript是单线程的,但浏览器不是。

有一个堆栈执行函数和语句。有一个队列,其中函数被排队等待执行。在事件表中定义了setTimeout和setInterval中定义的web,可以在特定的时间内保存该函数。

当javascript引擎逐行执行js文件时,如果它发现一行语句或函数调用它在堆栈上加载并执行,但如果它是setTimeout或setInterval调用,则与setTimeout或setInterval关联的函数处理程序将由time API (浏览器的web之一)取出,并将其保存到该时间。

一旦这一次结束,时间Api将该函数放在执行队列的末尾。

现在,该函数的执行取决于其他函数调用,这些函数调用位于队列中的前面。

注意:对window对象调用此函数调用。

setTimeout(function () {console.log(this)}, 300)

窗口{postMessage:ƒ,模糊:ƒ,焦点:ƒ,关闭:ƒ,frames: Window,…}

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22051209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档