事件循环Event Loop

在事件循环期间的某个时刻,运行时会从最先进入队列的消息开始处理队列中的消息。被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧。函数的处理会一直进行到执行栈再次为空为止;然后事件循环将会处理队列中的下一个消息(如果还有的话)。

目前成都创新互联公司已为1000多家的企业提供了网站建设、域名、网站空间、网站改版维护、企业网站设计、义县网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

"执行至完成"

每一个消息完整地执行后,其它消息才会被执行。这为程序的分析提供了一些优秀的特性,包括:当一个函数执行时,它不会被抢占,只有在它运行完毕之后才会去运行任何其他的代码,才能修改这个函数操作的数据。这个模型的一个缺点在于当一个消息需要太长时间才能处理完毕时,Web 应用程序就无法处理与用户的交互,例如点击或滚动。为了缓解这个问题,浏览器一般会弹出一个“这个脚本运行时间过长”的对话框。一个良好的习惯是缩短单个消息处理时间,并在可能的情况下将一个消息裁剪成多个消息。

函数setTimeout接受两个参数:待加入队列的消息和一个时间值(可选,默认为 0)。这个时间值代表了消息被实际加入到队列的最小延迟时间。如果队列中没有其它消息并且栈为空,在这段延迟时间过去之后,消息会被马上处理。但是,如果有其它消息,setTimeout消息必须等待其它消息处理完。因此第二个参数仅仅表示最少延迟时间,而非确切的等待时间。

零延迟

零延迟并不意味着回调会立即执行。以 0 为第二参数调用setTimeout并不表示在 0 毫秒后就立即调用回调函数。

其等待的时间取决于队列里待处理的消息数量。在下面的例子中,"这是一条消息"将会在回调获得处理之前输出到控制台,这是因为延迟参数是运行时处理请求所需的最小等待时间,但并不保证是准确的等待时间。

setTimeout需要等待当前队列中所有的消息都处理完毕之后才能执行,即使已经超出了由第二参数所指定的时间

JS执行顺序

  1. JS是从上到下一行一行执行。
  2. 如果某一行执行报错,则停止执行下面的代码。
  3. 先执行同步代码,再执行异步代码

事件循环的执行过程

  • 同步代码,调用栈执行后直接出栈
  • 异步代码,放到Web API中,等待时机,等合适的时候放入回调队列(callbackQueue),等到调用栈空时eventLoop开始工作,轮询
  • 微任务执行时机比宏任务要早
  • 微任务在DOM渲染前触发,宏任务在DOM渲染后触发

网站栏目:事件循环Event Loop
网站地址:http://scyanting.com/article/dsojigi.html