JavaScript 事件循环机制 event loop

同步任务、异步任务

JavaScript是一门单线程语言,分为同步任务和异步任务

同步任务

在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。

异步任务
  • 不进入主线程、而进入"任务队列"的任务
  • 只有等主线程任务全部执行完毕,"任务队列"的任务才会进入主线程执行。
  • 异步任务分为宏任务和微任务
  • 宏任务:宿主(Node、浏览器)发起的,会触发新一轮Tick的事件
    • 比如:script (可以理解为外层同步代码)、定时器回调、UI rendering/UI事件、postMessage,MessageChannel 、setImmediate,I/O(Node.js)、DOM 事件回调、ajax 回调
  • 微任务:JS引擎发起的事件
    • 比如:promise的回调、MutationObserver 的回调、object.observe(已废弃;Proxy 对象替代) 4. process.nextTick(Node.js)
  • 宏队列、微队列:js 中用来存储待执行回调函数的队列包含 2 个不同特定的列队
    • 宏队列:用来保存待执行的宏任务(回调)
    • 微队列:用来保存待执行的微任务(回调)

执行顺序(即事件循环)

image.png

  1. 先执行所有同步任务,碰到异步任务放到任务队列中
  2. 同步任务执行完毕,开始执行当前所有的异步任务
  3. 先执行微队列里面所有的微任务
    1. 设置进入微任务检查点的标志为true。
    2. 当事件循环的微队列不为空时:
      1. 选择一个最先进入microtask队列的microtask;
      2. 设置事件循环的当前运行任务为已选择的microtask;
      3. 运行microtask;
      4. 设置事件循环的当前运行任务为null;
      5. 将运行结束 的microtask从microtask队列中移除。
    3. 对于相应事件循环的每个环境设置对象(environment settings object),通知它们哪些promise为 rejected。
    4. 清理indexedDB的事务。
    5. 设置进入microtask检查点的标志为false。
    6. 更新界面渲染。
  4. 然后执行一个宏任务,如果没有宏任务可以选择,则会 跳转至微任务的执行步骤。
    1. 将事件循环的当前运行宏任务设置为已选择的宏任务。
    2. 运行宏任务。
    3. 将事件循环的当前运行任务设置为null。
    4. 将运行完的宏任务从宏任务队列中移除。
  5. 然后再执行所有的微任务
  6. 再执行一个宏任务,再执行所有的微任务·······依次类推到执行结束。

当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件, 然后再去宏任务队列中取出一个 事件。同一次事件循环中, 微任务永远在宏任务之前执行。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值