nodejs事件循环与多进程(一)——事件循环允许Node.js执行非阻塞I/O操作 & js是操作DOM,决定了单线程 & 事件循环之宏任务setTimeout在后、微任务promise在前
nodejs事件循环与多进程
why
- 事件循环对于深入理解nodejs异步至关重要
- fs, net,http,events
- 事件循环是企业面试中的最高频考题之一
- 能驾驭nodejs多进程是一名资深前端工程师的标志
课程介绍
- 了解事件循环的概念
- 学习浏览器中的事件循环机制
- 学习nodejs中的事件循环机制
- 了解多进程,多线程之间的区别
- 学习nodejs中的多进程并使用cluster来开启多进程
学习目标
- 深入掌握浏览器与nodejs中的事件循环机制,并且能理解它们之间的区别
- 使用cluster开启多进程
第一章 事件循环介绍
浏览器中的事件循环
为了协调事件(event),用户交互(user interaction),脚本(script),渲染(rendering),网络(networking)等,用户代理(user agent)必须使用事件循环(event loops)。
To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as described in this section. Each agent has an associated event loop.
- 事件:PostMessage, MutationObserver等
- 用户交互: click, onScroll等
- 渲染: 解析dom,css等
- 脚本:js脚本执行
nodejs中的事件循环
- 事件: EventEmitter
- 非阻塞I / O:网络请求,文件读写等
- 脚本:js脚本执行
事件循环的本质
在浏览器或者nodejs环境中,运行时对js脚本的调度方式就叫做事件循环。
- promise在前,setTimeout在后
setTimeout(() => {
console.log('setTimeout') }, 0); Promise.resolve().then(() => {
console.log('promise'); }); console.log('main'); // 执行顺序是 1. main 2. promise 3. setTimeout
第二章 浏览器事件循环
Javascript为什么是单线程的?
浏览器js的作用是操作DOM,这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
任务队列
单线程就意味着所有任务需要排队,如果因为任务cpu计算量大还好,但是I/O操作cpu是闲着的。所以js就设计成了一门异步的语言,不会做无畏的等待。任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
setTimeout(() => {
console.log('setTimeout') }, 0); console.log('main1'); console.log('main2'); // 执行顺序是 1. main1 2. main2 3. setTimeout
主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
宏任务与微任务
除了广义的同步任务和异步任务,JavaScript 单线程中的任务可以细分为宏任务(macrotask)和微任务(microtask)。
- macrotask: script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。
- microtask:process.nextTick, Promise, Object.observe, MutationObserver。
- 宏任务进入主线程,执行过程中会收集微任务加入微任务队列。
- 宏任务执行完成之后,立马执行微任务中的任务。微任务执行过程中将再次收集宏任务,并加入宏任务队列。
- 反复执行1,2步骤
setTimeout(() => {
console.log('setTimeout') }, 0); Promise.resolve().then(() => {
console.log('promise'); }); console.log('main'); // 1. main 2. promise 3. setTimeout
执行机制
高频面试题
setTimeout(() => {
console.log('setTimeout'); }, 0); Promise.resolve().then(() => {
console.log('promise'); Promise.resolve().then(() => {
console.log('promise2'); }); }); console.log('main'); // 执行顺序是 main、promise、promise2、setTimeout
每轮事件循环执行一个宏任务和所有的微任务。
嵌套执行顺序
setTimeout(() => {
Promise.resolve().then(() => {
console.log('promise'); }); }, 0); Promise.resolve().then(() => {
setTimeout(() => {
console.log('setTimeout'); }, 0); }); console.log('main'); // 打印顺序是 —— 1. main 2. promise 3. setTimeout // 突破口:谁先进入io,谁先出来
任务队列一定会保持先进先出的顺序执行。
交叉显示
到此这篇nodejs事件循环与多进程(一)——事件循环允许Node.js执行非阻塞IO操作 & js是操作DOM,决定了单线程 & 事件循环之宏任务setTimeout在后、微任务promise在前的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/hd-nodejs/10818.html