美文网首页
nodejs笔记

nodejs笔记

作者: 不要变成发抖的小喵喵喵喵喵喵 | 来源:发表于2017-07-09 22:01 被阅读0次

    菜鸟教程

    简介

    简单的说 Node.js 就是运行在服务端的 JavaScript。
    Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
    Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

    安装

    参考菜鸟教程

    NPM使用介绍

    新版的nodejs已经集成了npm,可以通过查看版本号测试是否安装成功:

    $ npm -v
    4.2.0
    

    使用淘宝NPM镜像

    $ npm install -g cnpm --registry=https://registry.npm.taobao.org
    
    // 使用cnpm来安装模块
    $ cnpm install [name]
    

    安装模块

    $ npm install <Module Name>       #本地
    $ npm install <Module Name> -g    #全局
    

    查看安装信息

    $ npm list -g
    

    查看某个模块的版本号

    $ npm list grunt
    

    卸载模块

    $ npm uninstall express
    

    更新模块

    $ npm update express
    

    搜索模块

    $ npm search express
    

    创建模块,会生成 package.json 文件

    $ npm init
    

    版本号

    语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。

    1. 如果只是修复bug,需要更新Z位。
    2. 如果是新增了功能,但是向下兼容,需要更新Y位。
    3. 如果有大变动,向下不兼容,需要更新X位。

    回调函数

    阻塞代码

    var fs = require("fs");
    
    var data = fs.readFileSync('input.txt');
    
    console.log(data.toString());
    console.log("程序执行结束!");
    

    非阻塞代码

    var fs = require("fs");
    
    fs.readFile('input.txt', function (err, data) {
        if (err) return console.error(err);
        console.log(data.toString());
    });
    
    console.log("程序执行结束!");
    

    阻塞实例在文件读取完后才执行完程序。
    非阻塞实例我们不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。
    阻塞是按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数,我们就需要写在回调函数内。

    事件循环

    1. nodejs是单进程单线程应用程序,通过事件回调支持并发,所以性能非常高。
    2. nodejs的每一个API都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。
    3. nodejs基本上所有的事件机制都是用设计模式中的观察者模式实现。
    4. nodejs单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数。
    var events = require('events');
    var eventEmitter = new events.EventEmitter();
    // 监听器1
    var listener1 = function listener1(){
        console.log('监听器 listener1 执行。');
    }
    // 监听器2
    var listener2 = function listener2(){
        console.log('监听器 lisrener2 执行。');
    }
    // 绑定连接事件,处理函数为listener1
    eventEmitter.addListener('connection',listener1);
    // 绑定连接事件,处理函数为listener1
    eventEmitter.addListener('connection',listener2);
    
    var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
    console.log(eventListeners + ' 个监听器监听连接事件。');
    // 处理连接事件
    eventEmitter.emit('connection');
    // 移除监绑定的 listener1 函数
    eventEmitter.removeListener('connection',listener1);
    console.log('listener1 不再受监听。');
    // 触发连接事件
    eventEmitter.emit('connection');
    
    eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
    console.log(eventListeners + ' 个监听器监听连接事件。');
    
    eventEmitter.emit('error');
    console.log('程序执行完成。');
    
    
    
    // 执行结果
    $ node main.js
    2 个监听器监听连接事件。
    监听器 listener1 执行。
    监听器 listener2 执行。
    listener1 不再受监听。
    监听器 listener2 执行。
    1 个监听器监听连接事件。
    程序执行完毕。
    

    Buffer(缓冲区)

    在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

    创建Buffer类

    var buf = new Buffer([10,20,30,40,50]);;
    console.log(buf);
    // <Buffer 0a 14 1e 28 32>
    
    var buf2 = new Buffer('www.runoob.com','utf-8');
    console.log(buf2);
    // <Buffer 77 77 77 2e 72 75 6e 6f 6f 62 2e 63 6f 6d>
    
    var buf3 = new Buffer(10);
    console.log(buf3);
    // <Buffer 00 00 00 00 00 00 00 00 00 00>
    

    写入缓冲区

    var len = buf3.write('www.runoob.com');
    console.log('写入字节数:' + len);
    

    从缓冲区读取数据

    console.log(buf.toString('ascii'));
    console.log(buf.toString('ascii',0,5));
    console.log(buf.toString('utf8',0,5));
    console.log(buf.toString(undefined,0,5));
    console.log(buf.toJSON());
    

    缓冲区合并

    var buffer1 = new Buffer('菜鸟教程');
    var buffer2 = new Buffer('www.runoob.com');
    var buffer3 = Buffer.concat([buffer1,buffer2]);
    console.log('buffer3 内容: '+buffer3.toString());
    

    缓冲区比较

    var buff1 = new Buffer('ABC');
    var buff2 = new Buffer('ABCD');
    var result = buff1.compare(buff2);
    
    if(result < 0){
        console.log(buff1 + ' 在 ' + buff2 + '之前');
    }else if(result == 0){
        console.log(buff1 + ' 与 ' + buff2 + '相同');
    }else{
        console.log(buff1 + ' 在 ' + buff2 + '之后');
    }
    

    拷贝缓冲区

    var b1 = new Buffer('ABC');
    var b2 = new Buffer(3);
    b1.copy(b2);
    console.log('b2 content: '+b2.toString());
    

    缓冲区裁剪

    var buffer1 = new Buffer('runoob');
    // 剪切缓冲区
    var buffer2 = buffer1.slice(0,2);
    console.log("buffer2 content: " + buffer2.toString());
    

    缓冲区长度

    var buffer = new Buffer('www.runoob.com');
    //  缓冲区长度
    console.log("buffer length: " + buffer.length);
    

    Stream(流)

    Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。
    Node.js,Stream 有四种流类型:

    1. Readable - 可读操作。
    2. Writable - 可写操作。
    3. Duplex - 可读可写操作.
    4. Transform - 操作被写入数据,然后读出结果。

    所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

    1. data - 当有数据可读时触发。
    2. end - 没有更多的数据可读时触发。
    3. error - 在接收和写入过程中发生错误时触发。
    4. finish - 所有数据已被写入到底层系统时触发。

    从流中读取数据

    var fs = require("fs");
    var data = '';
    
    // 创建可读流
    var readerStream = fs.createReadStream('input.txt');
    
    // 设置编码为 utf8。
    readerStream.setEncoding('UTF8');
    
    // 处理流事件 --> data, end, and error
    readerStream.on('data', function(chunk) {
       data += chunk;
    });
    
    readerStream.on('end',function(){
       console.log(data);
    });
    
    readerStream.on('error', function(err){
       console.log(err.stack);
    });
    
    console.log("程序执行完毕");
    

    写入流

    var fs = require("fs");
    var data = '菜鸟教程官网地址:www.runoob.com';
    
    // 创建一个可以写入的流,写入到文件 output.txt 中
    var writerStream = fs.createWriteStream('output.txt');
    
    // 使用 utf8 编码写入数据
    writerStream.write(data,'UTF8');
    
    // 标记文件末尾
    writerStream.end();
    
    // 处理流事件 --> data, end, and error
    writerStream.on('finish', function() {
        console.log("写入完成。");
    });
    
    writerStream.on('error', function(err){
       console.log(err.stack);
    });
    
    console.log("程序执行完毕");
    

    管道流,提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中,实现了大文件的复制过程。

    var fs = require("fs");
    
    // 创建一个可读流
    var readerStream = fs.createReadStream('input.txt');
    
    // 创建一个可写流
    var writerStream = fs.createWriteStream('output.txt');
    
    // 管道读写操作
    // 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
    readerStream.pipe(writerStream);
    
    console.log("程序执行完毕");
    

    链式流,通过连接输出流到另外一个流并创建多个对个流操作链的机制。链式流一般用于管道操作。用管道和链式来压缩和解压文件。

    压缩文件
    var fs = require("fs");
    var zlib = require('zlib');
    
    // 压缩 input.txt 文件为 input.txt.gz
    fs.createReadStream('input.txt')
      .pipe(zlib.createGzip())
      .pipe(fs.createWriteStream('input.txt.gz'));
      
    console.log("文件压缩完成。");
    
    var fs = require("fs");
    var zlib = require('zlib');
    
    // 解压 input.txt.gz 文件为 input.txt
    fs.createReadStream('input.txt.gz')
      .pipe(zlib.createGunzip())
      .pipe(fs.createWriteStream('input.txt'));
      
    console.log("文件解压完成。");
    

    模块系统

    模块公开的接口

    exports.world = function() {
      console.log('Hello World');
    }
    
    
    // 调用方式
    var hello = require('./hello');
    hello.world();
    

    模块接口

    //hello.js 
    function Hello() { 
        var name; 
        this.setName = function(thyName) { 
            name = thyName; 
        }; 
        this.sayHello = function() { 
            console.log('Hello ' + name); 
        }; 
    }; 
    module.exports = Hello;
    
    
    
    
    // 调用方式
    var Hello = require('./hello'); 
    hello = new Hello(); 
    hello.setName('BYVoid'); 
    hello.sayHello(); 
    

    模块接口的唯一变化是使用 module.exports = Hello 代替了exports.world = function(){}。 在外部引用该模块时,其接口对象就是要输出的 Hello 对象本身,而不是原先的 exports。

    函数

    一个函数可以作为另一个函数的参数

    function say(word) {
      console.log(word);
    }
    
    function execute(someFunction, value) {
      someFunction(value);
    }
    
    execute(say, "Hello");
    

    匿名函数

    function execute(someFunction, value) {
      someFunction(value);
    }
    
    execute(function(word){ console.log(word) }, "Hello");
    

    HTTP服务器

    var http = require("http");
    
    http.createServer(function(request, response) {
      response.writeHead(200, {"Content-Type": "text/plain"});
      response.write("Hello World");
      response.end();
    }).listen(8888);
    
    //或
    
    var http = require("http");
    
    function onRequest(request, response) {
      response.writeHead(200, {"Content-Type": "text/plain"});
      response.write("Hello World");
      response.end();
    }
    
    http.createServer(onRequest).listen(8888);
    

    路由

    router.js

    function route(pathname) {
      console.log("About to route a request for " + pathname);
    }
    
    exports.route = route;
    

    server.js

    var http = require("http");
    var url = require("url");
    
    function start(route) {
      function onRequest(request, response) {
        var pathname = url.parse(request.url).pathname;  
        console.log("Request for " + pathname + " received.");
    
        route(pathname);
    
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write("Hello World");
        response.end();
      }
    
      http.createServer(onRequest).listen(8888);
      console.log("Server has started.");
    }
    
    exports.start = start;
    

    index.js

    var server = require("./server");
    var router = require("./router");
    
    server.start(router.route);
    

    相关文章

      网友评论

          本文标题:nodejs笔记

          本文链接:https://www.haomeiwen.com/subject/cedhhxtx.html