js异步机制、事件循环、Promise执行顺序

本文详细探讨了JavaScript的异步机制,包括事件循环、任务队列、宏任务和微任务。解释了同步任务和异步任务的执行顺序,以及在浏览器和Node.js中的事件循环区别,特别是process.nextTick和Promise.then的执行优先级。
摘要由CSDN通过智能技术生成

看了阮老师的《再谈Event Loop》,有些地方还是不太清楚,所以又查了一些资料,资料链接在下面的参考中,总结一下。

线程

浏览器是多线程的,其中有

  • 渲染引擎线程:负责页面的渲染
  • JS引擎线程:负责JS的解析和执行
  • 定时触发器线程:处理定时事件,比如setTimeout, setInterval
  • 事件触发线程:处理DOM事件
  • 异步http请求线程:处理http请求

渲染引擎就是如何渲染页面,Chrome/Safari/Opera用的是Webkit引擎,IE用的是Trident引擎,FireFox用的是Gecko引擎。不同的引擎对同一个样式的实现不一致,就导致了经常被人诟病的浏览器样式兼容性问题。

不同浏览器的JS引擎也各不相同,Chrome用的是V8,FireFox用的是SpiderMonkey,Safari用的是JavaScriptCore,IE用的是Chakra。

其中渲染线程和JS引擎线程不能同时进行。平时我们说的js单线程只是JS引擎线程,而异步就是靠这些其他的线程来处理实现的,然后再通过事件循环、任务队列来传到js线程中。

事件循环

首先我们都知道js有同步和异步任务。

  • 同步任务是指在js主线程上排队执行的任务,只有前一个任务执行完毕,后一个同步任务才能执行。

  • 异步任务不在主线程执行,任务在主线程定义后到其他线程去执行,执行完毕后,会将结果放入任务队列,主线程的执行栈为空时,会读取任务队列,执行其中的任务。每个异步任务都和回调函数相关联。

JS引擎线程从消息队列中读取任务是不断循环的,每次栈被清空后,都会在消息队列中读取新的任务,如果没有新的任务,就会等待,直到有新的任务,这就叫事件循环。

每一个 JavaScript 运行的"线程环境"都有一个独立的 Event Loop,每一个 Web Worker 也有一个独立的 Event Loop。

异步任务可分为 task 和 microtask 两类,不同的API注册的异步任务会依次进入自身对应的队列中,然后等待 Event Loop 将它们依次压入执行栈中执行。

具体过程

  • 执行完主执行线程中的任务。
  • 取出Microtask Queue中任务执行直到清空。
  • 取出Macrotask Queue(task)中一个任务执行。
  • 取出Microtask Queue中任务执行直到清空。
  • 重复3和4。

task主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)

microtask主要包含:Promise.then、MutaionObserver、process.nextTick(Node.js 环境)

在 Node 中,会优先清空 next tick queue,即通过process.nextTick 注册的函数,再清空 other queue,常见的如Promise;此外,timers(setTimeout/setInterval) 会优先于 setImmediate 执行,因为前者在 timer 阶段执行,后者在 check 阶段执行。

setTimeout/Promise 等API便是任务源,而进入任务队列的是他们指定的具体执行任务。来自不同任务源的任务会进入到不同的任务队列。其中setTimeout与setInterval是同源的。

由于JS引擎线程空闲后,会先查看是否有事件可执行,接着再处理其他异步任务。所以如果click事件和setTimeout都该执行时,先执行click事件的回调函数。例如下面程序

setTimeout(function(){
   
    console.log('timer');
}, 0)

function waitFiveSeconds(){
   
    var now = 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值