我是软件开发的初学者。据我所知,JavaScript 从左到右、从上到下依次运行,只在调用函数时跳过行并返回回车。如果是这样的话,当程序当前被其他计算占用时,如何记住运行设置为每 2000 毫秒执行一次的 setInterval 函数?
在幕后,JavaScript 应该运行一排"任务"(事件循环(。任务是函数。在函数结束时,JavaScript 会检查队列以查看是否应该调用另一个函数。
setInterval 仅将函数推送到此队列中,以便在指定时间运行。
JavaScript 只有 1 个线程,因此如果繁重的计算占用大量时间,队列中的事件将被推迟到该任务完成。
这就是为什么你不想在JS中运行阻塞函数。
尽管每个 JavaScript 代理都有一个执行线程 - 即所谓的"事件循环",但运行时可能用于为此提供服务的执行线程数不受限制。
传递给诸如setInterval
、setTimeout
或requestAnimationFrame
等函数的回调被安排在JavaScript运行时环境中由"magic"(即隐藏逻辑(运行。
此隐藏逻辑计划在适当时间(例如,在间隔过后(在作业队列上插入回调。当与回调关联的作业到达相关作业队列的前端,并且当执行线程可用于为其提供服务时,将从队列中删除该作业,为其实例化堆栈帧(也称为执行上下文(,将其推送到调用堆栈上,然后开始执行。
异步函数(如setTimeout
、setInterval
和requestAnimationFrame
(的逻辑在其他规范中定义(例如。W3C/WHATWG(,并由主机应用程序(例如Web浏览器或NodeJS实例(实现。这些函数不是由 ECMAScript 规范定义的。
另一方面,异步承诺行为是在 ECMAScript 规范中指定的。