JS中的事件循环

javascript 单线程指的是浏览器中负责解释和执行 javascript 代码的只有一个线程,即为 js 引擎线程,但是浏览器的渲染进程是提供多个线程的,如下:

  • js 引擎线程
  • 事件触发线程
  • 定时器触发线程
  • 异步 http 请求线程
  • GUI 渲染线程

事件循环和事件队列的维护是由事件触发线程控制的。

事件触发线程线程同样是由浏览器渲染引擎提供的,它会维护一个事件队列。

js 引擎遇到上文所列的异步任务后,会交个相应的线程去维护异步任务,等待某个时机,然后由事件触发线程将异步任务对应的回调函数加入到事件队列中,事件队列中的函数等待被执行。

js 引擎在执行过程中,遇到同步任务,会将任务直接压入执行栈中执行,当执行栈为空(即 js 引擎线程空闲),事件触发线程会从事件队列中取出一个任务(即异步任务的回调函数)放入执行在栈中执行。

执行完了之后,执行栈再次为空,事件触发线程会重复上一步的操作,再从事件队列中取出一个消息,这种机制就被称为事件循环(Event Loop)机制。

console.log('script start');

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

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');
// script start
// script end
// promise1
// promise2
// timer over

所有的任务都划分到宏任务和微任务下:

macrotask: script 主代码块、setTimeout、setInterval、requestAnimationFrame、node 中的setimmediate 等。
microtask: Promise.then catch finally、MutationObserver、node 中的process.nextTick 等。
js 引擎首先执行主代码块。

执行栈每次执行的代码就是一个宏任务,包括任务队列(宏任务队列)中的。执行栈中的任务执行完毕后,js 引擎会从宏任务队列中去添加任务到执行栈中,即同样是事件循环的机制。

当在执行宏任务遇到微任务 Promise.then 时,会创建一个微任务,并加入到微任务队列中的队尾。

微任务是在宏任务执行的时候创建的,而在下一个宏任务执行之前,浏览器会对页面重新渲染(task >> render >> task(任务队列中读取))。同时,在上一个宏任务执行完成后,页面渲染之前,会执行当前微任务队列中的所有微任务

1 先执行主体代码(宏任务);

2 遇到同步代码,在执行栈中直接执行;

3 遇到 settineout 异步宏任务 ,放入宏任务任务队列中;

4 遇到promise .reslove部分执行栈直接执行;then 函数 放入微任务异步任务队列里;

5 遇到同步任务 直接执行;

6 执行栈全部清空;同步任务执行完后,开始第一个事件循环,到任务队列中检查有没有微任务;有,放入执行栈执行;

7 如此往复检查任务队列;再放入执行栈执行;再检查,再执行,叫事件循环;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值