likes
comments
collection
share

事件循环机制在浏览器和Node中的区别

作者站长头像
站长
· 阅读数 15

浏览器跟Node.js都是基于事件驱动的系统,他们的事件循环机制都是通过消息队列来实现的。然而,在具体实现上,两者还是有一些区别:

1、执行环境不同: 浏览器中的事件循环主要运行在Javascript引擎和渲染引擎之间,而Node.js中的事件循环是运行在单独的的线程中。因此,在浏览器中,事件循环跟渲染进程共享同一个线程,可能会出现线程阻塞。

2、宏任务和微任务的实现方式不同

在浏览器中,宏任务和微任务是通过HTML5规范中定义的消息队列来实现的。所有的异步任务都被分为宏任务和微任务两种类型,并依次加入到对应的队列中。当当前的宏任务执行完毕后,会立即执行所有的微任务,然后再选择下一个宏任务执行。 常见的宏任务包括:setTimeout, setInterval, DOM事件等,常见的微任务包括:Promise.then, MutationObserve等。

在Node.js中,宏任务和微任务的实现方式有所不同。Node.js使用libuv库提供的事件循环机制来管理宏任务,而使用process.nextTick()方法来实现微任务。在Node.js的事件循环中,所有的宏任务都被分为6个不同的阶段,每个阶段会执行一些同步和异步的操作。当当前阶段的所有任务执行完毕后,才会执行process.nextTick()的为任务队列。

function test () { 
    console.log('start') 
    setTimeout(() => { 
        console.log('children2') 
        Promise.resolve().then(() => {
            console.log('children2-1')
        }) 
    }, 0) 
    setTimeout(() => { 
        console.log('children3') 
        Promise.resolve().then(() => {
            console.log('children3-1')
        })
    }, 0) 
    Promise.resolve().then(() => {
        console.log('children1')
    }) 
    console.log('end') 
}
test()

// 以上代码在 node11 以下版本的执行结果(先执行所有的宏任务,再执行微任务)

// start
// end
// children1
// children2
// children3
// children2-1
// children3-1

// 以上代码在 node11 及浏览器的执行结果(顺序执行宏任务和微任务)

// start
// end
// children1
// children2
// children2-1
// children3
// children3-1

3、在处理 I/O 操作和定时器方面有些许不同

Node.js 中采用异步 I/O 和非阻塞 I/O,可以提供更高效的事件循环机制。而浏览器中,大多数的 I/O 操作都是通过 Web APIs 实现的,这些 API 通常是基于异步回调函数实现的。在处理定时器方面,Node.js 提供了 setImmediate() 方法来代替 setTimeout() 函数,在性能上有所提升。

总之,尽管浏览器和 Node.js 都采用了事件循环机制来管理异步任务,但它们的具体实现方式有所不同。了解这些差异对于开发人员来说是很重要的,因为它们可以帮助我们更好地理解和优化自己的代码

转载自:https://juejin.cn/post/7236194665011511356
评论
请登录