js事件循环机制

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

调用栈(执行上下文栈)

在了解事件循环之前很有必要知道调用栈的概念。首先我们栈是先进后出的执行任务。

而调用栈也是按照这个顺序执行,同时当我们运行全局代码或是每个函数的时候都会创建相对应的执行上下文。当我们执行代码的时候,首先会创建一个全局的执行上下文,之后遇到调用函数就会把调用函数的执行上下文入栈,等执行完后进行出栈,然后继续往后执行直到整个调用栈为空。文字描述过于抽象,以代码举例。

<script type="text/javascript">


function first() { 

  console.log('Inside first function'); 

  second(); 

  console.log('Again inside first function'); 

}
function second() { 

  console.log('Inside second function'); 

}

console.log('Inside Global Execution Context');

first(); 

</script>

看这js 脚本,大家应该很容易就能看出输出顺序,但是在每个函数是如何进栈出栈的呢,我列出了一个流程图,可以清晰地看出调用栈的活动

image.png

Eventloop

因为js是单线程的,如果我们都是同步执行任务,只有一个任务出栈后才能入栈执行另一个任务,当达到一定体积的时候势必会产生阻塞。所以就引入了异步的执行任务。

image.png

  1. 同步任务和异步任务进入不同的流程,同步任务进入主线程,异步的进入event table 并注册函数
  2. 当指定的事情完成时,event table 会将这个函数移入 event queue
  3. 主线程内的任务执行完毕为空,会去 event queue 读取对应的函数,进入主线程执行。
  4. 上述过程不断重复,也就是event loop 的流程

而异步任务分为宏任务和微任务。

宏任务

  • 整体script
  • Settimeout
  • Setinterval
  • setimmediate

微任务

  • Promise
  • Process.nexttick
  • MutationObserver

当主线程中的同步任务执行完毕后会去检查异步任务的event  queue,然后拿出微任务队列的任务先执行,如果所有微任务都执行完,并且主线程为空去拿宏任务队列的任务执行,宏任务永远是最后执行的

举个例子

console.log('script start')

async function async1() {

  await async2()

  console.log('async1 end')

}

async function async2() {

  console.log('async2 end')

}

async1()

setTimeout(function() {

  console.log('setTimeout')

}, 0)
new Promise(resolve => {

  console.log('Promise')

  resolve()

})

  .then(function() {

    console.log('promise1')

  })

  .then(function() {

    console.log('promise2')

  })

console.log('script end')

输出:

image.png

总体来说就是,如果按照脚本顺序,如果遇到同步任务或微任务按照脚本顺序执行,之后遇到是微任务和宏任务都先存入队列,先把微任务执行完后执行宏任务。

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
js事件循环机制是一种用于管理和执行任务的机制。在js中,事件循环机制负责处理用户交互事件、异步操作和定时任务等。 事件循环机制的核心是事件循环和任务队列。当有事件发生时(如用户点击按钮),事件被加入到任务队列中。js引擎会持续地从队列中取出任务并执行,直到队列为空。 任务分为两种类型:宏任务和微任务。宏任务包括用户交互事件、定时任务等,而微任务主要是由Promise对象的then方法产生的任务。在每次事件循环中,js首先执行当前宏任务,然后执行所有微任务,然后对页面进行重绘和渲染,然后进入下一次事件循环事件循环机制的重要性在于处理js的异步操作。当遇到一个异步操作时,如网络请求或定时器,js引擎不会立即执行异步任务,而是将其放入任务队列,等到主线程上的任务执行完成后再处理。这就使得js可以同时处理多个任务,提高了程序的性能和响应速度。 需要注意的是,js是单线程执行的,即每次只能执行一个任务。所以当一个任务执行时间过长时,就会造成页面的卡顿和无响应。因此,我们需要合理地使用事件循环机制,将耗时的任务分解为小块的异步任务,以保证页面正常运行和用户体验。 总而言之,js事件循环机制是一种用于管理和执行任务的机制,它通过任务队列和事件循环的方式,实现了js的异步处理,提高了程序的性能和响应速度。掌握事件循环机制对于编写高效并且流畅的js代码是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值