浏览器和nodejs的事件循环有什么区别(以及引申)?

111 阅读1分钟

单线程和异步

JS是单线程的(无论在浏览器还是在nodejs)

浏览器中JS执行和DOM渲染公用一个线程

异步

宏任务和微任务

宏任务,如setTimeout setInterval 网络请求

微任务,如Promise async/await

微任务在下一轮DOM渲染前执行,宏任务在DOM渲染之后执行

nodejs异步

Nodejs同样使用ES语法,也是单线程,也需要异步

异步任务也分:宏任务 + 微任务

但是,他的宏任务和微任务,分不同的类型,有不同的优先级

nodejs宏任务类型和优先级(从上到下)

Timers —— setTimeout   setInterval

I/O —— callbacks - 处理网络流,TCP的错误回调

Idle,prepare —— 闲置状态(nodejs内部使用)

Poll轮调 —— 执行 poll 中的I/O队列

check检查 —— 存储 setImmediate 回调

close callbacks —— 关闭回调,如socket.on(‘close’)

nodejs 微任务类型和优先级

包括:promise, async/await,process.nextTick

注意,process.nextTick 优先级最高

nodejs  event loop(事件循环**)**

执行同步代码

执行微任务(process.nextTick优先级最高)

按顺序执行6个类型的宏任务(每个人物结束时都执行当前的微任务)

答案

浏览器和nodejs的event loop 流程基本相同

nodejs宏任务和微任务分类型,有优先级

注: 在开发过程中如果有需求,推荐使用setTmmediate代替process.nextTick

代码演示:

event loop

<script>    console.log('start')    setTimeout(() => {      console.log(timeout)    })    Promise.resolve().then(() => {      console.log('promise then')    })    console.log('end')    // ajax(url, fn) // 假设 300ms    // Event Loop 继续监听    // 宏任务 MarcoTask Queue    // () => {    //   console.log(timeout)    // }    // fn    // 1000ms 后,fn    //  DOM 渲染    // 微任务 MicroTask Queue    // () => {    //   console.log('promise then')    // }    // const p = document.createElement('p')    // p.innerHTML = 'new paragraph'    // document.body.appendChild(p)    // const list = document.getElementsByTagName('p')    // console.log('length---', list.length)    // console.log('start')    // // 渲染之后    // setTimeout(() => {    //   const list = document.getElementsByTagName('p')    //   console.log('length on timeout', list.length)    //   alert('阻塞 timeout')    // })    // // 渲染之前    // Promise.resolve().then(() => {    //   const list = document.getElementsByTagName('p')    //   console.log('length on promise', list.length)    //   alert('阻塞 promise')    // })    // console.log('end')
</script>

nodejs异步(执行方式)

console.log('start')setImmediate(() => {  console.log("setImmediate")})setTimeout(() => {  console.log('timeout')})Promise.resolve().then(() => {  console.log('Promise then')})process.nextTick(() => {  console.log('nextTick')})console.log('end')