事件循环!

事件循环


首先, JavaScript是一门单线程的语言,意味着同一时间内只能做一件事,但是这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是 事件循环

那么事件是什么呢?

事件是特定情况下触发的操作。这里的操作是用函数封装起来的,所以,事件就是在特定情况下触发的函数。
例如:

  • dom元素相关事件,在用户单击页面上的按钮或页面加载完成时触发;
  • 定时器中,在特定时间间隔后触发其绑定函数;
  • ajax请求中,在请求响应时,才会触发回调函数;
  • promise中,在其内代码有了结果后,再触发 then 函数;

同步任务与异步任务

在 JavaScript 中,事件有同步与异步之分。在 JavaScript 中,常见的同步和异步事件包括:

  • 同步事件:在主线程上排队执行的任务
  1. 代码执行:JavaScript 代码通常按照从上到下的顺序同步执行,即一行一行执行,直到遇到阻

塞操作或者遇到异步事件为止。

  1. 函数调用:同步函数调用会阻塞代码执行,直到函数执行完成并返回结果。
  • 异步事件:任务不直接进入主线程,而是由事件触发线程调度,在满足特定条件时先将异步任务放入事件处理队列(任务队列或者微任务队列)中,等待主线程空闲时处理。
  1. 定时器:通过 setTimeout() 、 setInterval() 等函数创建的定时器是异步事件,它们会在

指定的时间间隔之后触发回调函数。并且注意一点,当设置定时器时,浏览器会将定时器任务

放入任务队列中。在 JavaScript 中,任务队列中的任务会按照顺序执行,并且会等待当前执行

栈中的任务执行完成后才执行。因此,定时器回调函数的实际触发时刻可能会受到其他任务执

行时间的影响。

  1. 事件监听器:通过 addEventListener() 等函数注册的事件监听器是异步事件,它们会在事

件发生时触发回调函数。

  1. Promise:Promise 是一种用于处理异步操作的方式,它可以表示一个异步操作的结果,并在

操作完成或失败时触发相应的回调函数

同步任务与异步任务的运行流程图如下:
在这里插入图片描述

从上面我们可以看到,同步任务进入主线程,即主执行栈,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。上述过程的不断重复就事件循环。

宏任务与微任务

  • 宏任务

    • script(可以理解为外层同步代码)

    • setTimeout/setinterval

    • Urendering/Ul事件

    • postMessage, MessageChannel5setlmmediate, l/0(Node.js)

  • 微任务

    • Promise的then方法

    • async 方法中,await 语句行后面的代码

    • MutaionObserver

    • Object.observe(已废弃;Proxy 对象替代)

    • process.nextTick(Node.js)

执行机制

  • 当执行一个宏任务时,如果遇到微任务就将他放到微任务事件队列中
  • 当前宏任务执行完成后,会查看微任务的事件队列,然后将里面的所有微任务依次执行完
  • 然后再次执行宏任务,循环

练习一下

async function async1() {
    console.log('async1 start')
    await async2()
    console.log('async1 end')
}
async function async2() {
    console.log('async2')
}
console.log('script start')
setTimeout(function () {
    console.log('settimeout')
})
async1()
new Promise(function (resolve) {
    console.log('promise1')
    resolve()
}).then(function () {
    console.log('promise2')
})
console.log('script end')

1、首先执行主线程,从上到下执行,直到9行,直接打印

2、10行遇到定时器,宏任务,放到宏任务队列中,不执行内部代码

3、13行执行async1函数,先打印2行,遇到await,执行同行代码(将下面的代码放入微队伍中),打印7行

4、14行promise进入执行15行,17行遇到then,将下面的代码放入微任务队伍中

5、执行20行

6、首先执行微任务,先执行4行的第一个微任务,然后执行then后面的微任务

7、微任务执行完执行宏任务,也就是第十行,打印第11行的内容

所以最后的结果是:script start、async1 start、async2、promise1、script end、async1 end、promise2、settimeout

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值