nodejs-基础大杂烩(待整理)

2019年11月20日 阅读数:25
这篇文章主要向大家介绍nodejs-基础大杂烩(待整理),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
优势:安装简易,能自动配置环境变量
缺点:更新和更换版本需从新安装(这个能够用包管理器解决,不是问题)

高手推荐使用开源的NVM包管理器来更新和安装node,可能这个包在linux平台上比较好用吧javascript


globaljava

requirenode

modulelinux

processgit

这些都是在node中能用而在google浏览器中很差用的功能angularjs

windowsgithub

locationweb

documentredis

consolemongodb

这些是在google浏览器中好用的功能



var relay = require('./relay');

这条语句寻找的,要么是relay.js,要么是relya/index.js

var os = require('os');

os的object在node的系统定义里面


经常使用开发工具

webstorm

sublime text

linux

redis

mongodb

这些工具均可以在windows上实现

集成开发环境可使用vs code or vs


node服务器特色

1.不依赖其余特定的服务器软件(如apache、Nginx、IIS )

2.node.js 代码处理请求的逻辑

3.node.js 代码负责web服务器的各类“配置”



三种简单的路由方法:

1.path

2.Router

3.route


中间件技术:

1.Connect : node.js的中间框架

2.分层处理

3.每层实现一个功能


node.js核心功能

1.node是一个js的执行环境,其实是对V8的封装,使得V8在非浏览器的环境下执行的更好

2.node对一些特殊用例进行了优化

3.提供了替代的API

4.nodejs使用事件驱动,非阻塞I/O模型而得以轻量和高效

5.很是合适在分布式设备上运行的数据密集型的实时应用


Nodejs优势或特色

1.Restful API

2.单线程(这是一个坑,国内技术文章误传)

3.node能够在不新增线程的状况下,依然能够对任务进行并行处理

4.它经过事件轮询(event loop ) 处理请求

5.尽量的避免阻塞操做,取而代之,多使用非阻塞操做

6.支持websocket

7.不容许用户锁上程序

8.要求用户不断的处理新事物,所以很适合网络编程

9.在服务器上要与不少客户端通讯,必须处理网络连接

10.node开发服务器比传统语言更加方便


express

1.一个基于nodejs平台的灵活、简洁的应用开发框架

2.提供强大的特性,帮助建立各类web和移动应用

3.丰富的HTTP快捷方法和任意排列组合的Connect中间件,让建立健壮、友好的API变的快速又简单

4.Express不对nodejs已有的特性进行二次抽象,只是在其上扩展了web应用所须要的基本功能


关键词:

express开发框架相似于ASP.NET MVC框架

jade模版引擎相似于Razor引擎

stylus样式框架:CSS预处理器,CSS框架

Mean全栈解决方案:mongodb+express+angularjs+nodejs


nodejs能够用来

1.Web socket Server

2.Fast file upload client

3.ad server

4.any real-time data apps


Blocking-code   阻塞式代码

non-Blocking-code 非阻塞式代码



全局对象 : global

__dirname  :输出的当前文件的路径

__filename  :输出当前文件的路径和文件名

console

   console.log()

   console.info()

   console.error()

   console.warn()

   console.time()     

   consoel.timeEnd() 统计代码的执行时间,配合console.time()使用

process 

   process.stdout   标准输出  console.log调用的就是process.stdout.write("what")函数

   process.stderr   标准错误输出

   process.stdin     读取键盘输入

1
2
3
4
process.stdin.setEncoding( 'utf-8' );
process.stdin.on( 'data' , function (data){
     console.log(data);
})
1
2
3
4
5
process.stdin.setEncoding( 'utf-8' );
process.stdin.on( 'readable' , function (){
        var data = process.stdin.read();
        console.log(data);
});

监听退出事件

1
2
3
process.on( 'exit' ,funciton(){
       console.log( 'program will exit' );
})

监听中断事件 SIGINT --> signal interrupted 

1
2
3
process.on( 'SIGINT' ,funciton(){

      console.log('program will exit');

      process.exit();

})

   process.args

封装了咱们在node中输入的命令,以数组的形式展现,是 一个数组,第0项是node命令所在的目录,第二项是当前文件所在的绝对文件路径,第三项才开始是具体的参数。。。。

1
console(process.args);


   process.cwd()  --->展现执行node命令所在的目录

node的重定向命令

1
node console.js 1 >log.txt 2 > tt.txt

将第一条命令输出内容输出到log.txt

将第二条命令输出内容输出到tt.txt




object类型

   做用:功能相对单一,传输数据,保存数据和方法,以集合方式来组织

  初始化:构造函数方法,字面量方法

基本包装类型

Global对象

Math对象



Ryan dahl 是nodejs之父

关于高性能服务器的思考

process 13MB

10GB / 13MB = 787并发


thread 2MB

10GB / 2MB = 5120并发


事件驱动  Event loop

  什么是事件驱动,用户发起的HTTP请求,点击,打开文件,都是一个事件

单线程 / 全部用户

资源消耗极小


Watcher

  向watcher询问是否有事件须要处理

  timer watcher

  fs watcher 

  udp / req watcher 

  process watcher

Handles

  由watcher产生具体要处理的事件

  setTimeout

  当时间到达时,产生事件,执行handle(handle就是执行传入的回调函数)

 

Event loop --> watcher --> handles 


为何console.log()执行完成后退出

为何http.server()能够一直让程序执行

当event loop 中没有watcher的时候退出进程


Node中的Event Driven 实现

windows : IOCP 

Linux : epoll 

Mac : kqueue

Solaris : events ports


Event Driven 的问题

单线程阻塞的问题

一旦阻塞,事件的处理就变的低效


阻塞问题

磁盘 I/O 和 网络 I/O 的访问阻塞CPU执行

进行磁盘I/O和网络I/O时,CPU浪费

后续计算没法进行


没有完美的非阻塞I/O,经过线程池结合事件驱动实现


选择javascript缘由

1.成熟的事件驱动模式

2.没有I/O库,没有历史包袱,利于构建非阻塞的I/O库


V8 

1.直接生成机器码

2.分代式GC

3.优化




分层架构

引入libuv层

分别实现windows和linux平台的功能

分别编译


单线程服务大量的请i去

异常致使进程退出时,会丢失大量用户请i求


单线程问题

1.多核CPU利用问题

2.不该该浪费服务器资源


进程间的消息传递

1.进程间不共享数据

2.经过消息传递信息



子进程 / Cluster


分离监控和业务

充分利用硬件资源




模块

基于CommonJS Module 规范构建

公用模块平台 NPM


异步编程问题

Promise 

EventProxy

Async / Step 


在 C++或 C#中,当咱们谈到对象,指的是类或者结构体的实例。对象根
据他们实例化的模板(就是所谓的类),会拥有不一样的属性和方法。但在
JavaScript 里对象不是这个概念。在 JavaScript 中,对象就是一个键/
对的集合 -- 你能够把 JavaScript的对象想象成一个键为字符串类型的字
典。


但若是 JavaScript 的对象仅仅是键/值对的集合,它又怎么会拥有方法呢?好吧,这里的值能够是字符串、数字或者……函数。


在浏览器中,顶级做用域为全局做用域,在全局做用域下经过 var something即定义了一个全局变量。可是在 Node 中并不如此,顶级做用域并不是是全局做用域,在 Node 模块中经过 var something 定义的变量仅做用于该模块。


require.paths
require()的搜索路径数组,你能够修改该数组添加自定义的搜索路径
将一个新的搜索路径插入到搜索列表的头部。
1
require.paths.unshift( '/usr/local/node' );
__filename
当前正在执行的脚本的文件名。这是一个绝对路径,可能会和命令行参数中传入的文件名不一样。
1
2
console.log(__filename);
// /Users/mjr/example.js
__dirname
Timers 定时器
setTimeout(callback, delay, [arg], [...])
设定一个 delay 毫秒后执行 callback 回调函数的计划。返回值 timeoutId 被用于 clearTimeout()。能够设定要传递给回调函数的参数

clearTimeout(timeoutId)

setInterval(callback, delay, [arg], [...])
设定一个每 delay 毫秒重复执行 callback 回调函数的计划。返回值
intervalId 可被用于 clearInterval()。能够设定要传递给回调函数的参数。

clearInterval(intervalId)

Folders as Modules 目录做为模块
第一种方法是在目录的根下建立一个名为 package.json 的文件,它指定了一个 main 模块。一个 package.jso 文件的例子以下面所示:
1
2
{ "name" : "some-library" ,
"main" : "./lib/some-library.js" }
若是在目录中没有 package.json 文件, node 将试图在该目录中加载 index.js或 index.node 文件。例如,在上面的例子中没有 package.json 文件,
require('./some-library')将试图加载

1
2
 ./some-library/index.js
 ./some-library/index.node
Caching 缓存
模块在第一次加载后将被缓存。这意味着(相似其余缓存)每次调用
require('foo')若是解析到相同的文件,那么将返回同一个对象

module
经过module对象能够访问到当前模块的一些相关信息,但最多的用途是替换
当前模块的导出对象。例如模块导出对象默认是一个普通对象,若是想改为一
个函数的话,可使用如下方式。
1
2
3
module.exports = function () {
      console.log( 'Hello World!' );
};

一个模块中的JS代码仅在模块第一次被使用时执行一次,并在执行过程当中初始
化模块的导出对象。以后,缓存起来的导出对象被重复利用。


NODE_PATH环境变量
与PATH环境变量相似,NodeJS容许经过NODE_PATH环境变量来指定额外的模块搜索路径。
NODE_PATH环境变量中包含一到多个目录路径,路径之间在Linux下使用:分隔,在Windows下
使用;分隔。例如定义了如下NODE_PATH环境变量:
NODE_PATH=/home/user/lib:/home/lib

当使用require('foo/bar')的方式加载模块时,则NodeJS依次尝试如下路径。
/home/user/lib/foo/bar
/home/lib/foo/bar


index.js
当模块的文件名是index.js,加载模块时可使用模块所在目录的路径代替
1
2
var cat = require( '/home/user/lib/cat' );
var cat = require( '/home/user/lib/cat/index' );

1
2
3
function copy(src, dst) {
     fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}

Buffer
1
var bin = new Buffer([ 0x68 , 0x65 , 0x6c , 0x6c , 0x6f ]);
1
bin[ 0 ]; // => 0x68;
Stream(数据流)
当内存中没法一次装下须要处理的数据时,或者一边读取一边处理更加高效
时,咱们就须要用到数据流。NodeJS中经过各类Stream来提供对数据流的操
做。Stream基于事件机制工做,全部Stream的实例都继承于NodeJS提供

1
2
3
4
5
6
7
var rs = fs.createReadStream(pathname);
             rs.on( 'data' , function (chunk) {
             doSomething(chunk);
});
     rs.on( 'end' , function () {
             cleanUp();
});
上边的代码中data事件会源源不断地被触发,无论doSomething函数是否处
理得过来。代码能够继续作以下改造,以解决这个问题。
1
2  
3
4
5
6
7
8
9
10
var rs = fs.createReadStream(src);
            rs.on( 'data' , function (chunk) {
            rs.pause();
            doSomething(chunk, function () {
            rs.resume();
});
});
            rs.on( 'end' , function () {
            cleanUp();
});
此外,咱们也能够为数据目标建立一个只写数据流,示例以下:
1
2
3
4
5
6
7
8
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
              rs.on( 'data' , function (chunk) {
              ws.write(chunk);
});
           rs.on( 'end' , function () {
              ws.end();
});

咱们把doSomething换成了往只写数据流里写入数据后,以上代码看起来就
像是一个文件拷贝程序了。可是以上代码存在上边提到的问题,若是写入速度
跟不上读取速度的话,只写数据流内部的缓存会爆仓。咱们能够根
.write方法的返回值来判断传入的数据是写入目标了,仍是临时放在了缓
存了,并根据drain事件来判断何时只写数据流已经将缓存中的数据写入
目标,能够传入下一个待写数据了。所以代码能够改造以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
rs.on( 'data' , function (chunk) {
if (ws.write(chunk) === false ) {
rs.pause();
}
});
rs.on( 'end' , function () {
ws.end();
});
ws.on( 'drain' , function () {
rs.resume();
});




简单使用的node教程挺好的

https://github.com/alsotang/node-lessons


nodejs异步带来的困扰也将破局,从callback到promise,从promise到generator,从generator到co,从co到async/await,不管如何generator/co和async/await会在2016年获得很是大的推广


目前这些的支持除了nodejs sdk和babel外,typescript也是一个比较好的选择









上一篇: PHP SOCKET编程
下一篇: 产品经理的初识