EventLoop笔记

 ​​​​​​node环境

Event Loop各阶段:

  1. - timers 阶段:这个阶段执行 setTimeout 和 setInterval 的回调函数。
  2. - I/O callbacks 阶段:不在 timers 阶段、close callbacks 阶段和 check 阶段这三个阶段执行的回调,都由此阶段负责,这几乎包含了所有回调函数。
  3. - idle, prepare 阶段(译注:看起来是两个阶段,不过这不重要):event loop 内部使用的阶段(译注:我们不用关心这个阶段)
  4. - poll 阶段:获取新的 I/O 事件。在某些场景下 Node.js 会阻塞在这个阶段。
  5. - check 阶段:执行 setImmediate() 的回调函数。
  6. - close callbacks 阶段:执行关闭事件的回调函数,如 socket.on('close', fn) 里的 fn

nextTick会在当前阶段执行完马上执行。

nextTick 既属于宏任务也属于微任务,主要是由他的实现方式决定的。 nexTick 实现方式是 promise,属于微任务,但是由于 IE 浏览器没有 promise,所以使用定时器的方式实现的,这又属于宏任务了。一般情况是微任务。

setImmediate是宏任务,只不过是比setTimeout要更快执行的宏任务。

主要记住三个阶段:

  • times(存放setTimeout、setInterval 宏任务的队列)
  • poll(等待)(nextTick在当前阶段的尾部执行)
  • check(setImmediate会存在这个队列中)

eventloop会在不停的循环执行这些阶段,当没有任务时,它会停留在poll阶段。实际上,大部分时间是停留在poll阶段的,因此setImmediate往往会优先于setTimeout先执行。

console.log('1');

setTimeout(() => {
  console.log('3');
}, 0);

async function async1() {
    console.log('4');
    await async2();
    console.log('5');
}

async function async2() {
    console.log('6');
}

async1();

new Promise(function(resolve) {
    console.log('7')
    resolve();
}).then(function() {
    console.log('8')
});

process.nextTick(function() {
    console.log('2');
});


console.log('9');

// 微任务队列 5 8
// 宏任务队列 3
// nextTick是当前阶段尾部,process.nextTick是在当前同步代码中调用的,也就是说同步代码执行完
//  会立即执行nextTick,打印出2
// 1 4 6 7 9  2 5 8 3

浏览器环境

在浏览器环境中只需要区分宏任务和微任务即可,微任务如promise由于宏任务setTimeout先执行,注意new Promise()是立即同步执行的,只有promise.then()里的内容是微任务。如果遇到await写法,可以改写为promise.then()然后来判断。

await是一个语法糖,await后面是一个返回promise的函数,如果函数里没有返回promise,它会自动封装为一个返回promise的函数。

简单来说,宏任务是一会儿执行的,微任务是马上执行的,执行顺序显而易见。

async function foo() {
  console.log('foo')
}
async function bar() {
  console.log('bar start')
  await foo()
  console.log('bar end')
}

console.log('script start')
setTimeout(function () {
  console.log('setTimeout')
}, 0)

bar();

new Promise(function (resolve) {
  console.log('promise executor')
  resolve();
}).then(function () {
  console.log('promise then')
})
console.log('script end') 

// 微任务 马上: bar end、promise then、
// 宏任务 一会儿: setTimeout、
/*
script start
bar start
foo
promise executor
script end
bar end
promise then
setTimeout、

*/

 

为什么会有event loop
因为js是单线程的,如果某段程序需要等待一会再执行,后面的程序都会被阻塞,这样也就带来了一些问题。为了解决这个问题,js出现了同步和异步两种任务,两种任务的差异就在于执行的优先级不同。event loop就是对任务的执行顺序做了详细的规范。

同步和异步任务
异步任务:异步任务分为宏任务和微任务。
常见的微任务有:Promise.then(),.then中的逻辑是微任务;process.nextTick(node环境)。
常见的宏任务有:setTimeout、setInterval、setImmediate(node环境)、xhr(发送网络请求),callback。
同步任务:除了上面的这些情况,都属于同步任务。

任务的执行顺序
先到后:同步任务 -> 微任务 -> 宏任务。

任务在哪里执行
无论是同步任务还是异步任务,都是在主线程执行。

什么是 event loop
事件循环(event loop)就是 任务在主线程不断进栈出栈的一个循环过程。任务会在将要执行时进入主线程,在执行完毕后会退出主线程。
下面就是这个循环的步骤:
1.把同步任务队列 或者 微任务队列 或者 宏任务队列中的任务放入主线程。
2.同步任务 或者 微任务 或者 宏任务在执行完毕后会全部退出主线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值