阅读 178

浏览器中的Event Loop

每天做个总结吧,坚持就是胜利!

    /**
        @date 2021-05-28
        @description 浏览器中的Event Loop
    */
复制代码

壹(序)

首先我们知道js是一门单线程且非阻塞的语言。

单线程是由于js主要的运行环境是浏览器,而浏览器中存在很多dom操作,假如js是一门多线程语言,那两个线程同时修改和删除同一个dom的时候,该怎么办?

非阻塞是js代码在执行过程中,遇到异步操作时,不会等待异步操作完成,而是将其挂起,等操作完成后执行相应的回调。而Event Loop就用来实现js非阻塞特性。

贰(解释)

那么什么是Event Loop呢?

一段js代码在执行过程中,同步代码会在主线程中依次执行,遇到异步代码时会等待执行完成后(主线程继续往下执行同步代码),将相应的回调压入任务队列中,等到主线程中的同步代码执行完成,会去任务队列中查看有没有需要执行的回调代码,有的话则执行,在这些回调中也是先执行同步代码,遇到异步代码则挂起,等待异步代码完成后压入任务队列,同步执行完成后再去查看任务队列中有没有需要执行的回调代码...这样一个循环过程,称为事件循环

看一段代码:

console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
console.log(3);
复制代码

首先同步执行代码console.log(1);,输出1,然后遇到异步的setTimeout,然后往下执行同步代码console.log(3);,输出3,同步代码执行完成后,去任务队列中取出setTimeout的回调执行,输出2;

叁(宏任务,微任务)

看下面一段代码:

console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
const p = new Promise((resolve, reject) => {
    resolve(4);  
});
p.then(val => {
    console.log(val)
});
console.log(3);
复制代码

按照刚刚的解释,应该是输出1,3,2,4,但是实际上是输出1,3,4,2

这是因为任务还分为宏任务微任务,执行的时候会首先执行完所有的微任务,再去执行宏任务;

宏任务:

  1. setInterval;
  2. setTimeout;
  3. setImmediate;
  4. I/O操作;

微任务:

  1. Promise;
  2. MutationObserver;

肆(练习)

做一道练习题:

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;
  2. 遇到setTimeout,压入任务队列,且是一个宏任务;
  3. 执行同步代码async1();输出async1 start;
  4. 遇到await,需先执行await之后的函数async2;输出async2;其后代码压入任务队列,且是一个微任务;
  5. 执行Promise中的同步代码,输出promise1resolve()后的代码压入任务队列,且是一个微任务;
  6. 执行同步代码,输出script end
  7. 此次循环中的所有同步代码执行完成,开始执行任务队列中的回调,首先是第4步压入的微任务,输出async1 end
  8. 继续执行第5步压入的微任务,输出promise2
  9. 执行完所有微任务,执行第2步压入的宏任务,输出setTimeout;

最终输出:script start, async1 start, async2, promise1, script end, async1 end, promise2, setTimeout

文章分类
前端
文章标签