nodejs笔记之:事件驱动,线程池,非阻塞,异常处理等

2023-11-07

nodejs笔记之:事件驱动,线程池,非阻塞,异常处理等

2016年05月01日 14:44:42 Johnny丶me 阅读数 4112更多

分类专栏: NodeJs Nodejs 硬实战 全栈工程师笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Tyro_java/article/details/51290419

事件驱动

事件驱动的模型:


这里写图片描述
 

事件驱动的原理:

原理总结:

Nodejs 会把所有请求和异步操作都放到一个事件队列中,用户的每一个请求就是一个事件。主线程先把普通代码执行完毕,然后会循环事件队列里的函数,如果遇到有IO的操作,nodejs会去线程池里拿出一个线程去执行IO的操作,执行完毕后再把拿到数据的回调函数,放到事件队列的尾部,继续事件循环。

线程池

线程池的概念:

Node是单线程的,这里的单线程仅仅是javascript执行在单线程中,V8引擎不支持io操作,在node中,无论是类unix还是windows平台内部完成IO的操作都有线程池。

在windows下,node实现IO异步的解决方案是iocp:调用异步方法,等待IO完成之后的通知,执行回调,用户无需考虑轮询,但是其内部仍然是线程池原理,不同之处在于这些线程池是由系统内核接受管理。 
在linux下,0.9.3版本之前的node是使用libeio配合libuv实现的异步IO,在此版本之后的node自行实现了线程池来完成异步io操作。 
本质上nodejs 是个多线程平台。如果有io操作,nodejs交给 中间层libuv去做,它的底层就是C或者C++来实现的,所以nodejs本质上还是个多线程平台。

IO 操作

io操作就是以流的形式,进行的操作,比如网络请求,文件读取写入。io操作也就是input和output的操作。

阻塞IO

在调用阻塞io时,应用程序需要等待io完成才能返回结果。 
阻塞io的特点:调用之后一定要等到系统内核层面完成所有操作之后,调用才结束。 
阻塞io造成CUP等待IO,浪费等待时间,CPU的处理能力不能得到充分利用。

非阻塞IO

为了提高性能,内核提供了非阻塞io,非阻塞io跟阻塞io的差别是调用之后会立即返回。 
阻塞io完成整个获取数据的过程,而非阻塞io则不带数据直接返回,要获取数据,还要通过问价你描述符再次读取。 
非阻塞io返回之后,cpu时间片可以用来处理其他事物,此时性能提升非常明显。

Nodejs中的异常处理

Node是单线程运行环境,一旦抛出异常,没有被处理,就会引起整个进程崩溃。 
Node的异常处理,对于保证系统稳定运行非常重要。 
Node有三种方式,处理一个错误 : 
    1. throw 抛出异常。 
    2. 将错误对象传递给回调函数,由回调函数负责处理错误。 
    3. 使用try catch捕获异常有时候会不及时,合理的放置 trycath 去捕获,在异步内部,而不是在异步的外层去捕获,就像是下面的在回调函数内部去try catch 。

回调函数

Node采用: 将错误对象作为第一个参数传入回调函数,这样就避免了捕获错误与发生错误不在一个时间段上的问题。

回调函数的设计

对于一个函数需要定义回调函数,node统一规定:

  1. 回调函数一定作为参数的最后一个参数出现:

    Function foo(arg1,arg2,callback){}
    • 1
  2. 回调函数的第一个参数默认接收错误对象,第二个参数才是真正的回调函数(便于外界获取调用的错误情况)

    // 执行一个doRead() 函数,假设有这么一个函数,主要看里面的异常处理
    doRead(obj,function(err,res){
        if(err) throw err; // err 是错误对象
        console.log(res); // res 是具体的结果或者数据
     } )
    • 1
    • 2
    • 3
    • 4
    • 5
  3. 强调错误优先

    • 错误优先的回调函数,第一个参数是上一步的错误对象
    • 通过判断回调函数中的err是否为null,来检测异步操作过程是否出现错误,我们用下面的例子来举例说明:

      const fs = require('fs');
      // 定义一个读文件函数
      function readFile(path, callback) {
        fs.readFile(path, 'utf8', function (err, data) {
          if (err) {
            return callback(err, null);
          }
          callback(null, '输出的数据为:' + data);
        });
      }
      
      readFile('./data/index.html', function (err, data) {
        if (err) {
          throw err;
        }
        console.log(data);
      });
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

总结:

  1. Node规定,如果某个函数需要作为参数,则回调函数是最后一个参数,另外,回调函数本身的第一个参数,约定为上一步传入的错误对象
  2. 传统的错误捕捉机制try catch,尽量不要使用,在异步操作中容易出错。
  3. 一旦异步操作发生错误,就把错误对象传递到回调函数,如果没有发生错误,回调函数的第一个参数就是null,如果不是null,就肯定出错了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nodejs笔记之:事件驱动,线程池,非阻塞,异常处理等 的相关文章

随机推荐

  • Android 多种方式修改Settings数据库

    若有获取Context的其他方法 还请走过路过的大佬不吝赐教 Android原生涉及到了众多属性及默认值 其中有部分就存储在Settings数据库中 地址如下 Android frameworks base core java androi
  • CLI 命令行实用程序开发实战 - Agenda

    CLI 命令行实用程序开发实战 Agenda 实验内容 实验过程 安装必要的包 初始化并添加相应指令 完善指令 register login entity中相应函数的实现 测试 实验内容 功能需求 设计一组命令完成 agenda 的管理 例
  • 利用python的matplotlib包绘制氢原子的径向分布函数

    to get the angular momentum of a oneparticle system import matplotlib pyplot as plt import numpy as np from scipy import
  • 华为OD机试 - 素数之积(Java)

    题目描述 RSA加密算法在网络安全世界中无处不在 它利用了极大整数因数分解的困难度 数据越大 安全系数越高 给定一个 32 位正整数 请对其进行因数分解 找出是哪两个素数的乘积 输入描述 一个正整数 num 0 lt num lt 2147
  • Springboot+SpringSecurity实现权限控制(二、用户登录认证)

    配置Security核心配置类 将WebSecurityConfig放在auth包下 右击鼠标 gt 点击Generate gt 点击Override Methods 选择下面的三个configure 禁用防护 http csrf disa
  • Js的script标签中的id作用

    首先 和普通的html标签一样 script也是可以作为html元素来处理的 而Dom的节点都是可以有id属性的 其实 script中的id还是有用的 比如如果页面需要加载的JS文件过多 那样最好是写一个JS文件用来加载这些JS文件 比如可
  • java.security.InvalidKeyException: IOException : Detect premature EOF

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 要 加密和解密 要公钥和私钥 报错 java security InvalidKeyException IOException Detect premature EOF 其
  • [LeetCode] All Paths From Source to Target 从起点到目标点到所有路径

    LeetCode 797 All Paths From Source to Target 解题报告 Python C LeetCode All Paths From Source to Target 从起点到目标点到所有路径 Leetcod
  • 网站的服务器区域可以造假吗,如何伪造DNS服务器?

    DNS 服务器是进行域名和与之相对应的 IP 地址转换的服务器 正常情况下 用户访问域名网站 首先从 DNS 服务器上或权威名称服务器上获取域名对应的 IP 地址 然后根据该 IP 地址访问网站 为了能够使用户混淆 netwox 工具提供了
  • 服务器上的数据库文件,服务器上数据库文件

    服务器上数据库文件 内容精选 换一换 在云服务器上部署SAP HANA数据库软件 本章安装以SAP HANA 2 0安装包为例 用户可自行从官网下载安装包 然后将下载的安装包上传到待安装SAP HANA的云服务器 hana001 与 han
  • 【vue】element-表单中,下拉框选中某个值后,同步更新其他输入框的值

    一 实现的效果 jobName下拉框选择任意一个后 jobId同步变成对应的值 二 实现 2 1 数据结构 1 jenkinsList 2 3 id 10 4 dictType 1 5 dictValue 小程序1 6 extra 0 7
  • 七十四.JAVA典型静态方法的实现

    public class LianXi 计算一个整数的绝对值 public static int abs int x if x lt 0 return x else return x 计算一个浮点数的绝对值 public static do
  • 电脑键盘部分按键失灵_笔记本个别键盘失灵用不了怎么修复

    笔记本电脑用的时间长可能或出现键盘失灵或者个别键盘用不了的问题 导致键盘失灵的原因有很多 笔记本不像台式电脑 直接换一个键盘就可以了 如果部分键位失灵可能因为键位老化或者误操作引起的 接下来小编和大家分享笔记本个别键盘失灵用不了的修复方法
  • 焊接机器人电流电压焊接速度_焊接速度——机器人真的比人快吗?

    近年来 随着工业机器人的发展 机器人是否将取代人类已成为了这个时代最流行的话题之一 尤其是作为工业 裁缝 的焊接机器人 有人说机器人的焊接速度是人工焊接速度的2倍以上 也有人说机器人焊接和人工焊接的速度是一样的 因为它们的参数基本都一样 那
  • serial消息查看指令

    cat proc tty driver serial 查看当前设备上的所有串口的接收和发送的数据
  • this.$message

    前言 在平时的开发过程中 我们总是先写好一个组件 然后在需要的页面中用 import 引入即可 但如果是下面这种类型的组件呢 image 上面这种类型的浮层提示有一个很大的特点 就是使用频率特别高 几乎每个页面都会用到它 于是乎我们就要在每
  • 新唐科技

    目录 芯片实拍图 目标应用 主要特点 官网免费获取Keil License 导入LIC 开源仓库地址 新唐单片机开发keil常用pack下载 新唐开发板资料 新唐开发相关论坛 偶然看到一款新唐科技的开发板 LQFP 48 pin封装 是一款
  • 三相全桥电压型PWM逆变器(交直交)Simulink仿真

    概述 整个pwm调制过程是交流 直流 交流这么一个过程 首先利用三相全桥整流电路再经过一个大电容从而得到一个纹波较小的直流电源 之后利用这个电源作为逆变电路电源 通过三个标准正弦波和三角波比较生成脉冲控制IGBT三相桥 最终得到PWM调制的
  • VMware 导入虚拟机

    直接把虚拟机的 ovf文件 或者文件 gt 打开 拖到 VMware 里就能触发导入 导入遇到的问题 解压P4learning 发生SHA digest of file p4 learning disk1 vmdk does not mat
  • nodejs笔记之:事件驱动,线程池,非阻塞,异常处理等

    nodejs笔记之 事件驱动 线程池 非阻塞 异常处理等 2016年05月01日 14 44 42 Johnny丶me 阅读数 4112更多 分类专栏 NodeJs Nodejs 硬实战 全栈工程师笔记 版权声明 本文为博主原创文章 遵循