node基础(1)---eventloop事件环

##在浏览器中,全局作用域是window,而在node中是global。

但是我们可以直接var a=1;console.log(window.a),但是我们不能console.log(global.a),因为node在执行的时候会形成一个闭包来实现模块化。

node解决了什么

Node的首要目标是提供一种简单的,用于创建高性能服务器的开发工具
Web服务器的瓶颈在于并发的用户量,对比Java和Php的实现方式

Node在处理高并发,I/O密集场景有明显的性能优势

  • 高并发,是指在同一时间并发访问服务器
  • I/O密集指的是文件操作、网络操作、数据库,相对的有CPU密集,CPU密集指的是逻辑处理运算、压缩、解压、加密、解密

Web主要场景就是接收客户端的请求读取静态资源和渲染界面,所以Node非常适合Web应用的开发。

Console

在Node.js中,使用console对象代表控制台(在操作系统中表现为一个操作系统指定的字符界面,比如 Window中的命令提示窗口),一下列出一些基本用法:

  • console.log  (标准输出
  • console.info(标准输出
  • console.error(错误输出
  • console.warn (错误输出
  • console.dir (
    console. dir( Array. prototype,{ showHidden: true})
  • console.time  
  • console.timeEnd
  • console.trace
  • console.assert  (断言 
    console. assert(( 1+ 1== 3), 'error')

线程和进程

        线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个 进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程 在运行中呈现出间断性。线程也有就绪阻塞运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

        多线程靠的是切换时间片,这个过程中可能会浪费资源;计算在分配资源时,按照进程为单位。而node 中是单线程(主线程),并且是异步非阻塞的。

谈谈浏览器

  • 用户界面-包括地址栏、前进/后退按钮、书签菜单等
  • 浏览器引擎-在用户界面和呈现引擎之间传送指令(浏览器的主进程)
  • 渲染引擎,也被称为浏览器内核(浏览器渲染进程)
  • 一个插件对应一个进程(第三方插件进程)
  • GPU提高网页浏览的体验(GPU进程)

由此可见浏览器是多进程的,并且从我们的角度来看我们更加关心浏览器渲染引擎

其他线程 #

  • 浏览器事件触发线程(用来控制事件循环,存放setTimeout、浏览器事件、ajax的回调函数)
  • 定时触发器线程(setTimeout定时器所在线程)
  • 异步HTTP请求线程(ajax请求线程)

单线程特点是节约了内存,并且不需要在切换执行上下文。而且单线程不需要管锁的问题,这里简单说下锁的概念。例如下课了大家都要去上厕所,厕所就一个,相当于所有人都要访问同一个资源。那么先进去的就要上锁。而对于node来说。下课了就一个人去厕所,所以免除了锁的问题!


浏览器的事件环是先执行微任务再执行宏任务,但是这里面有个代码编译的时间线,不会把队列里的都执行完。(跟node不同)

为了方便理解执行栈的概念我们看个例子

function one(){
    let a = 1;
    two();
    function two(){
        let b = 2;
        three();
        function three(){
            console.trace()
            console.log(b)
        }
    }
}
one();

这个图就是代码执行的时候出来的执行栈(执行过程从下往上)。

·····#####################################

为了方便理解宏任务和微任务的执行顺序我们也来一个例子:

console.log(1)
setTimeout(function(){
    console.log(4)
},0)
let promise = new Promise(function(resolve,reject){
    console.log(3)
    resolve(100)
}).then(function(data){
    console.log(100)
    setTimeout(function(){
        console.log(5)
    },0)
})
console.log(2)

控制台会先输出13(new Promise的时候就立即执行)2,setTimeout的执行内容放到宏任务队列中,then执行内容放微任务中,最后在把输出5的也方到宏任务中,因为微任务先于宏任务执行,那么输出结果:


  • 1.所有同步任务都在主线程上执行,形成一个执行栈
  • 2.主线程之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
  • 3.一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,将队列中的事件放到执行栈中依次执行
  • 4.主线程从任务队列中读取事件,这个过程是循环不断的

整个的这种运行机制又称为Event Loop(事件循环)

###node系统

我们先来张图看看node是如何工作的

node system

  • 1.我们写的js代码会交给v8引擎进行处理
  • 2.代码中可能会调用nodeApi,node会交给libuv库处理
  • 3.libuv通过阻塞i/o和多线程实现了异步io
  • 4.通过事件驱动的方式,将结果放到事件队列中,最终交给我们的应用。

Node中的Event Loop

在libuv内部有这样一个事件环机制。在node启动时会初始化事件环



这里每一个阶段都对应一个事件队列,当event loop执行到某个阶段时会将当前阶段对应的队列依次执行。当队列执行完毕或者执行的数量超过上线时,会转入下一个阶段。这里我们重点关注poll阶段

node事件环跟浏览器的事件环类似唯一不同的是它是把队列的执行完才执行下个队列。

举个例子:

console.log(1);
console.log(2);
setTimeout(function(){
    console.log('setTimeout1')
    Promise.resolve().then(function(){
        console.log('promise')
    });
})
setTimeout(function(){
    console.log('setTimeout2');
});
这个用浏览器控制台和vscode运行出来的不一样,自己可以执行一下哦。










单线程特点是节约了内存,并且不需要在切换执行上下文。而且单线程不需要管锁的问题,这里简单说下锁的概念。例如下课了大家都要去上厕所,厕所就一个,相当于所有人都要访问同一个资源。那么先进去的就要上锁。而对于node来说。下课了就一个人去厕所,所以免除了锁的问题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值