Node基础知识笔记

Posted 过往将来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node基础知识笔记相关的知识,希望对你有一定的参考价值。

全文目录

Node.js简介

  1. Node.js就是运行在服务器端的javascript,Node.js是一个基于Chorme JavaScript运行时建立的一个平台。
  2. Node.js时一个事件驱动I/O服务器端JavaScript环境,性能很好

Node 应用简介

  1. 使用Node建立一个应用时,还同时实现了整个HTTP服务器,实际上,Web应用以及对应的Web服务器基本是一样的。
  2. Node.js应用的组成包含三部分:引入require模块,创建服务器,接收请求与相应请求
  3. 引入require模块:我们可以使用require指令来载入Node.js模块
  4. 创建服务器:服务器可以监听客服端的请求,类似与nginx等HTTP服务器。
  5. 接收请求与响应请求:服务器很容易创建,客户端可以使用浏览器或者终端发送HTTP请求,服务器接受请求后返回响应数据。

Node创建的hello world

  1. 创建一个server.js文件,输入以下内容
    var http = require('http');
    
    http.createServer(function (request, response) {
    
        // 发送 HTTP 头部 
        // HTTP 状态值: 200 : OK
        // 内容类型: text/plain
        response.writeHead(200, {'Content-Type': 'text/plain'});
    
        // 发送响应数据 "Hello World"
        response.end('Hello World\\n');
    }).listen(8888);
    
    // 终端打印如下信息
    console.log('Server running at http://127.0.0.1:8888/');
  1. 使用require指令来载入http模块,并将实例化的HTTP赋值给http
  2. 使用http.createServer()方法创建服务器,并使用listen方法绑定8888端口.函数通过request,response参数来接收和响应数据。
  3. 使用 node server.js 执行server.js文件,此时,在浏览器中访问http://127.0.0.1:8888/可以查看到hello world

npm知识点

npm 简介

  1. npm是随同node.js一起安装的报管理工具,能解决node.js代码部署上的很多问题。

npm的使用场景

  1. 使用npm可以从服务器端下载别人编写好的第三方包到本地使用
  2. 使用npm从服务器下载并安装别人编写的命令行程序到本地使用。
  3. 使用npm可以将自己编写的包或者命令行程序上传到npm服务器供别人使用

npm 命令集合

  1. 使用npm install 安装npm
  2. npm -v查看npm是否安装成功。
  3. npm install npm -g 来升级npm4.的版本。
  4. 使用npm配置淘宝镜像:npm install -g --registry=https://registry.npm.taobao.org.
  5. 注意:不用使用npm install -g cnpm --registry=https://registry.npm.taobao.org这种方式配置淘宝镜像,因为cnpm下载下来的第三方包的路径有时会很奇怪,会出现不可预知的错误!
  6. npm的安装分为本地安装local和全局安装globalnpm install express 本地安装express, npm install express -g 全局安装express.
  7. 如果出现此错误:npm err! Error: connect ECONNREFUSED 127.0.0.1:8087 ,解决办法为:$ npm config set proxy null
  8. npm list -g命令查看所有全局安装的模块!
  9. npm list grunt 查看某个模块的版本号.
  10. npm uninstall <Module Name> 卸载npm模块,卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:npm ls
  11. npm update <Module Name> 可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。。
  12. npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。
  13. npm search <Module Name> 搜索npm模块
  14. npm help <command>可查看某条命令的详细帮助,例如npm help install.
  15. npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
  16. npm init 创建一个模板生成package.json。让我们使用 npm 产生 package.json。

npm的具体使用

  1. 使用npm安装的模板语法:npm install <Module Name>,比如使用npm安装常用的Node的web框架express
  2. 在安装好了之后,express包就放在了根目录下的 node_modules 目录中,只需要通过 var express = require('express');的方式就可以引用该包,无需指定第三方包的路径。
  3. npm install express -g,全局安装 express包,不加-g默认为本地安装。

npm 本地安装详解

  1. 将安装包放在./node_modules下,(运行npm命令时所在的目录),如果没有node_modules目录,会在当前执行npm命令时生成node_modules目录。
  2. 可以通过require()来引入本地安装的包。

npm 全局安装详解

  1. 全局安装在安装包放在/uer/local 或者 你的node安装目录中!!注意:node的安装路径中!不要使用中文!!!不要使用中文!!!一定不要使用中文!!如果使用中文,在具体使用第三方包时会出现错误。
  2. 全局安装可以直接在cmd打开的命令行中使用、

npm 安装时异常的处理

  1. 使用 npm 安 装node_modules总是提示报错:报错:npm resource busy or locked.....。可以先删除以前安装的node_modules使用npm cache clean,然后再重新安装:npm install .

第三方包知识点

第三方包简介

  1. package.json的使用说明:package.json 位于模块的目录下,用于定义包的属性。
  2. name-包名,
  3. version-包的版本号
  4. description-包的描述
  5. homepage-包的官网url
  6. author-包的作者姓名
  7. contributors - 包的其他贡献者姓名。
  8. dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
  9. repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
  10. main - main 字段指定了程序的主入口文件,require(‘moduleName’) 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
  11. .keywords - 关键字

Node.js 回调函数

  1. 回调是一种异步相当于一个函数,回调函书被调用在完成既定任务,

回调函数

  1. Node.js的回调函数:Node.js异步编程的直接体现就是回调,异步编程依托于回调来实现,但是不能说使用了回调后程序就异步化了!回调函数再完成任务后就会被调用,Node使用了大量的回调函数,Node所有的API都支持回调函数。
    2.例如:一边读取文件,一边执行其他命令,再文件读取完成后,将文件内容作为回调函数的参数返回,这样再执行代码时就没有阻塞或者等待文件的I/O操作。这样提高了Node.js的性能,可以处理大量的并发请求。
  2. 回调函数一般作为函数的最后一个参数出现,function foo1(name, age, callbackName){},function foo2(value,callback1,callbackName){}

阻塞代码测试

  1. 在根目录下,创建一个input.txt文件,内容为:百度网址:www.baidu.com
  2. main.js文件中,代码如下:
    var fs = require('fs');在这里需要安装fs的包,如果不安装的话,会报错
    var data = fs.readFileSync('input.txt');
    console.log(data.toString());
    console.log("程序执行结束");
    
	在终端使用 node main.js。
	终端打印如下信息:
        百度网址:www.baidu.com
        程序执行结束
  1. 阻塞测试案例:是在文件读取完成后才执行程序,
  2. 阻塞时按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数.我们就需要写在回调函数内.

非阻塞代码测试

  1. main.js文件中的代码如下:
    var fs = require('fs');
    fs.readFile('input.txt',function(err,data){
        if (err) return console.error(err);
        console.log(data.toString());
    });
    console.log("程序执行结束");
    
	在终端使用 node main.js。
	终端打印如下信息:
        程序执行结束
        百度网址:www.baidu.com
  1. 非阻塞测试案例:我们不需要等待文件读取完,这样就可以在读取文件的同时执行接下来的代码.从而提高程序的性能。
  2. 阻塞时按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数.我们就需要写在回调函数内.

Node.js事件循环

  1. Node.js是单线程应用,但它通过事件和回调的概念支持并发。Node.js每个API都是异步的,作为一个单线程,node使用异步函数调用来维护并发。
  2. Node线程保持一个事件循环,每当任何一个任务完成后得到结果,node就触发通知事件侦听函数来执行相应的事件。
  3. Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.

事件驱动程序

  1. Node.js使用事件驱动模型,每当web server接收到请求,就把它关闭进行处理,然后再去服务下一个web请求,党这个请求完成之后,它被放回处理队列,当到达队列开头,这个结果就被返回给用户。

  2. 事件驱动模型非常高效,可扩展性很强,因为web server一直接受请求而不等待任何读写操作(也成为非阻塞式IO或者事件驱动IO)

  3. 在事件驱动模型中,会生成一个主循环来监听事件,每当检测到事件时触发回调函数。

  4. 事件驱动流程图如下所示
    在这里插入图片描述

  5. Node.js有多个内置事件,通过引入events模块,实例化EventEmitter类来绑定和监听事件

    var events = require('events');
    
   
    var eventEmitter = new events.EventEmitter();  // 创建eventmitter对象
    
    // 创建事件处理程序
    var connectHandler = function connected(){
        console.log('连接成功');
        eventEmitter.emit('data_received');// 触发data_received 事件
    }
    
   
    eventEmitter.on('connection',connectHandler); // 绑定connection 事件处理程序
    
    
    eventEmitter.on('data_received',function(){ // 使用匿名函数绑定 data_received 事件
        console.log('数据接受成功');
    })
    
    
    eventEmitter.emit('connection');// 触发 connection 事件
    console.log('程序执行完毕');
    
    在终端执行 node main.js 输出结果:
    连接成功
    数据接受成功
    程序执行完毕

Node应用程序工作流程

  1. Node应用程序中,执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数。
    var fs = require("fs");
    fs.readFile("input.txt",function(err,data){
        if(err){
            console.log(err.stack);
            return;
        }
        console.log(data.toString());
    })
    console.log("程序执行完毕")
  1. readFile()是异步函数用于读取文件,如果读取文件过程中发生错误,错误err对象就会输出错误信息。
  2. 如果没有发生错误就会跳过 err 对象的输出,文件内容就会通过回调函数输出、

进程和线程的概念

  1. 进程是指系统中正在运行的一个应用程序,程序一旦运行就是进程,进程是系统进行资源分配的独立实体,每个进行拥有独立的地址空间。
  2. 一个进程之间可以拥有多个线程,每个线程使用其所属进程的栈空间
  3. 线程是进程的一个实体,是进程的一条执行路径,线程是CPU独立运行和独立调度的基本单位。

Node EventEmitter 事件发射器详解

  1. Node所有的异步I/O操作在完成时都会发送一个事件到事件队列
  2. Node里面很多对象都会分发事件,一个 net.Server 对象会在每次有新连接时触发一个事件,
  3. 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。

Node EventEmitter 类`

  1. events 模块只提供了一个对象: events.EventEmitter
  2. EventEmitter 的核心就是事件触发与事件监听器功能的封装。
  3. EventEmitter 对象如果在实例化时发生错误,会触发 error 事件,当添加新的监听器时,newListener事件会被触发,当监听器被移除时,removeListener事件被触发。
    实例一:简单介绍EventEmitter的用法
    
    var EventEmitter = require('events').EventEmitter; 
    var event = new EventEmitter(); 
    event.on('some_event', function() { 
        console.log('some_event 事件触发'); 
    }); 
    setTimeout(function() { 
        event.emit('some_event'); 
    }, 1000);1秒后,输出some_event 事件触发,这是因为event对象注册了事件some_event的一个监听器,然后通过setTimeout在1秒后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。
  1. EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。
  2. 对于每个事件,EventEmitter 支持 若干个事件监听器。当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。
    实例二:EventEmitter绑定事件和触发事件
    var events = require('events'); 
    var emitter = new events.EventEmitter(); 
    emitter.on('someEvent', function(arg1, arg2) { 
        console.log('listener1', arg1, arg2); 
    }); 
    emitter.on('someEvent', function(arg1, arg2) { 
        console.log('listener2', arg1, arg2); 
    }); 
    emitter.emit('someEvent', 'arg1 参数 A', 'arg2 参数 B'); 

emitter 为事件 someEvent 注册了两个事件监听器,然后触发了 someEvent 事件。两个事件监听器回调函数被先后调用。 这就是EventEmitter最简单的用法。

EventEmitter 属性介绍:

  1. addListener(event,listener) 为指定事件添加一个监听器到监听器数据的尾部

  2. on(event,listener)为指定事件注册一个监听器,接受一个字符串event和一个回调函数

    server.on('connection', function (stream) {
        console.log('someone connected!');
    });
    
  3. once(event,listener)为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器

       server.once('connection', function (stream) {
         console.log('Ah, we have our first user!');
        });
    
  4. removeListener(event, listener) 移除指定事件的某个监听器,监听器必须时该事件已经注册过的监听器removeListener(event,listener)接受两个参数,第一个是事件名称,第二个是回调函数名称

     var callback = function(stream) {
              console.log('someone connected!');
        };
          server.on('connection', callback);
          server.removeListener('connection', callback);
    
  5. removeAllListeners([event]) 移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。

  6. setMaxListeners(n)默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于改变监听器的默认限制的数量。

  7. listeners(event) 返回指定事件的监听器数组

  8. emit(event,[arg1],[arg2],[...]) 按照监听器的顺序执行每个监听器,如果事件有注册监听返回true,否则返回 false

EventEmitter 方法介绍:

  1. events.emitter.listenerCount(eventName)//推荐返回指定事件的监听器数量。

EventEmitter 事件介绍

  1. newListener(event,listener) 在添加新监听器时被触发,event是字符串,事件名称,listener 处理事件函数

  2. removeListener(event,listener)从指定监听器数组中删除一个监听器,此操作将会改变处于被删监听器之后的那些监听器的索引。

    实例三:通过 connection(连接)事件演示了 EventEmitter 类的应用。
    var events = require('events');
    var eventEmitter = new events.EventEmitter();
    
    // 监听器 #1
    var listener1 = function listener1() {
       console.log('监听器 listener1 执行。');
    }
    
    // 监听器 #2
    var listener2 = function listener2() {
      console.log('监听器 listener2 执行。');
    }
    
    // 绑定 connection 事件,处理函数为 listener1 
    eventEmitter.addListener('connection', listener1);
    
    // 绑定 connection 事件,处理函数为 listener2
    eventEmitter.on('connection', listener2);
    
    var eventListeners = eventEmitter.listenerCount('connection');
    console.log(eventListeners + " 个监听器监听连接事件。");
    
    // 处理 connection 事件 
    eventEmitter.emit('connection');
    
    // 移除监绑定的 listener1 函数
    eventEmitter.removeListener('connection', listener1);
    console.log("listener1 不再受监听。");
    
    // 触发连接事件
    eventEmitter.emit('connection');
    
    eventListeners = eventEmitter.listenerCount('connection');
    console.log(eventListeners + " 个监听器监听连接事件。");
    
    console.log("程序执行完毕。");
    
    输出结果为:
    2 个监听器监听连接事件。
    监听器 listener1 执行。
    监听器 listener2 执行。
    listener1 不再受监听。
    监听器 listener2 执行。
    1 个监听器监听连接事件。
    程序执行完毕。

error事件介绍

  1. EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发error 事件。
  2. error 被触发时,EventEmitter规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。
  3. 一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。

继承 EventEmitter

  1. 我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。
  2. 具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。
  3. JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

Node Buffer(缓冲区)知识点

  1. JS语言本身只有字符串数据类型,没有二进制数据类型,但是在处理TCP流或者文件流的时候,必须用到二进制数据,因此在Node中定义了一个Buffer类,用来创建一个专门存放二进制数据的缓存区。
    2.``Buffer类是Node的核心库,Buffer为node带来了一种存储元素数据的方法,从而可以让Node处理二进制数据,每当Node中处理I/O操作中移动数据的时候,就可以使用Buffer`类。
  2. 原始数据存储在Buffer类的实例中,一个Buffer类相当于一个整数数组.
  3. 使用 Buffer.from() 接口去创建Buffer对象。

Buffer与字符编码

  1. Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。
  2. 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。
    const buf = Buffer.from('runoob', 'ascii');
    
    // 输出 72756e6f6f62
    console.log(buf.toString('hex'));
    
    // 输出 cnVub29i
    console.log(buf.toString('base64'));

Node支持的字符编码

  1. ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
  2. utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
  3. utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
  4. ucs2 - utf16le 的别名
  5. base64 - Base64 编码。
  6. latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
  7. binary - latin1 的别名。
  8. hex - 将每个字节编码为两个十六进制字符。

Buffer 提供了 API 来创建 Buffer 类:

  1. Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
  2. Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
  3. Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
  4. Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
  5. Buffer.from(buffer):复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
  6. Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例

利用Buffer写入Node缓冲区

  1. 写入 Node 缓冲区的语法:buf.write(string[, offset[, length]][, encoding]).
  2. string - 写入缓冲区的字符串。
  3. offset- 缓冲区开始写入的索引值,默认为 0 。
  4. length - 写入的字节数,默认为 buffer.length
    5.encoding - 使用的编码。默认为 ‘utf8’ 。
  5. 如果 buf没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。
  6. 返回实际写入的大小。如果buffer 空间不足, 则只会写入部分字符串。
    实例一:简单的缓冲区演示
    buf = Buffer.alloc(256);
    len = buf.write("www.baidu.com");
    
    console.log("写入字节数 : "+  len);

利用Buffer从缓冲区中读取数据

  1. 读取 Node 缓冲区数据的语法:buf.toString([encoding[, start[, end]]])
  2. encoding- 使用的编码。默认为 ‘utf8’ 。
    3.start - 指定开始读取的索引位置,默认为 0。
  3. end- 结束位置,默认为缓冲区的末尾。
  4. 返回值为:解码缓冲区数据并使用指定的编码返回字符串。
实例一:从缓冲区中读取数据的演示
    buf = Buffer.alloc(26);
    for (var i = 0 ; i < 26 ; i++) {
      buf[i] = i + 97;
    }
    
    console.log( buf.toString('ascii'));       // 输出: abcdefghijklmnopqrstuvwxyz
    console.log( buf.toString('ascii',0,5));   //使用 'ascii' 编码, 并输出: abcde
    console.log( buf.toString('utf8',0,5));    // 使用 'utf8' 编码, 并输出: abcde
    console.log( buf.toString(undefined,0,5)); // 使用默认的 'utf8' 编码, 并输出: abcde

将 Buffer 转换为 JSON 对象

  1. Node Buffer转换为 JSON 对象的函数语法格式:buf.toJSON()
  2. 当字符串化一个 Buffer实例时,JSON.stringify()会隐式地调用该 toJSON()
  3. 返回值为JSON对象
实例一:将 Buffer 转换为 JSON 对象
    const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
    const json = JSON.stringify(buf);
    
    // 输出: {"type":"Buffer","data":[1,2,3,4,5]}
    console.log(json);
    
    const copy = JSON.parse(json, (key, value) => {
      return value && value.type === 'Buffer' ?
        Buffer.from(value.data) :
        value;
    });
    
    // 输出: <Buffer 01 02 03 04 05>
    console.log(copy);

Buffer 缓冲区合并

  1. Node 缓冲区合并的语法:Buffer.concat(list[, totalLength])
  2. list - 用于合并的 Buffer对象数组列表。
  3. totalLength - 指定合并后Buffer对象的总长度。
  4. 返回一个多个成员合并的新 Buffer对象。
实例一:简单的Buffer缓冲区合并
    var buffer1 = Buffer.from(('百度'));
    var buffer2 = Buffer.from(('www.baidu.com'));
    var buffer3 = Buffer.concat([buffer1,buffer2]);
    console.log("buffer3 内容: " + buffer3.toString());

Buffer 缓冲区比较

  1. 缓冲区比较语法:buf.compare(otherBuffer);
  2. otherBuffer- 与 buf对象比较的另外一个 Buffer 对象。
  3. 返回一个数字,表示 buf在 `otherBuffer 之前,之后或相同。
实例一:Buffer缓冲区比较
    var buffer1 = Buffer.from('ABC');
    var buffer2 = Buffer.from('ABCD');
    var result = buffer1.compare(buffer2);
    
    if(result < 0) {
       console.log(buffer1 + DOM探索之基础详解——学习笔记

学习笔记:python3,代码片段(2017)

今日艰难笔记-浏览器和Node下的eventloop

C#学习笔记——需要注意的基础知识

从前慢-Node+Gulp+Promise+Express

TypeScript学习笔记之基础类型