事件循环 Eventloop

JavaScript是一种单线程语言,有同步和异步的概念,这就解决了代码阻塞的问题
同步任务:是直接放在主线程上排队依次执行,
异步任务:会放在任务队列中,若有多个异步任务则需要在任务队列中排队等待,任务队列类似于缓冲区,任务下一步会被移到调用栈然后主线程执行调用栈的任务。

浏览器的事件循环

在事件驱动的模式下,至少包含了一个执行循环来检测任务队列中是否有新任务。通过不断循环,去取出异步任务的回调来执行,这个过程就是事件循环,每一次循环就是一个事件周期。

浏览器的事件循环由一个宏任务队列+多个微任务队列组成。
首先,执行第一个宏任务:全局 Script 脚本。产生的的宏任务和微任务进入各自的队列中。执行完 Script 后,把当前的微任务队列清空。完成一次事件循环。接着再取出一个宏任务,同样把在此期间产生的回调入队。再把当前的微任务队列清空。以此往复。宏任务队列只有一个,而每一个宏任务都有一个自己的微任务队列,每轮循环都是由一个宏任务+多个微任务组成。

宏任务和微任务

任务队列其实不止一种,根据任务种类的不同,可以分为微任务(micro task)队列和宏任务(macro task)队列。常见的任务如下:
宏任务: script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务: Promise、MutaionObserver、process.nextTick(Node.js 环境);

例子

   setTimeout(() => {
      //setTimeout(1)
      console.log(0);
    }, 0);
    new Promise((res) => setTimeout(res, 0)//setTimeout(2)
    ).then(() => {
      console.log(1);
      setTimeout(() => {
        console.log(2); //setTimeout(3)
      }, 0);
      new Promise((r => r())).then(() => {
        console.log(3);  //promise(2)
      });
    });
    setTimeout(() => {
      console.log(4); //setTimeout(4)
    }, 0);
    new Promise((res) => res()).then(() => {
      console.log(5);  //promise(1)
    });

1.setTimeout(1),setTimeout(2),setTimeout(4)分别放入宏任务队列
2.promise(1)放入微任务队列
3.执行微任务队列,输出 5
4.微任务队列清空,执行setTimeout(1)输出0 ,执行setTimeout(1),promise(2)放入微任务队列,setTimeout(3)放入宏任务队列
5.执行同步任务输出1 微任务队列执行,输出3
6.微任务队列清空,执行宏任务队列setTimeout(4),setTimeout(3) 输出 4 2

结果:5 0 1 3 4 2

    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')

1.执行同步任务 输出 script start,script end
2.setTimeout放入宏任务队列,Promise放入微任务队列
3.执行微任务队列,输出 promise1,promise2
4.微任务队列清空,执行setTimeout输出setTimeout
结果:script start,script end,promise1,promise2,setTimeout

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')
}, 0)
async1()
new Promise(function (resolve) {
  console.log('promise1')
  resolve()
}).then(function () {
  console.log('promise2')
})
console.log('script end')

1.执行同步任务script start,输出script start,setTimeout放入宏任务队列
2.执行async1(),输出 async1 start,执行async2(),输出async2,await后面放入微任务队列,执行promise,输出promise1
3.promise放入微任务队列,输出同步任务script end
4.执行微任务队列,输出async1 end,promise2
5.清空微任务队列,执行宏任务队列,输出setTimeout
结果: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、付费专栏及课程。

余额充值