nodejs学习笔记

一、fs模块 文件系统模块

    1.Node.js 文件系统 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)

    2.引入文件模块
        var fs = require("fs");

    3.异步读取txt文本使用

    fs.readFile('文本url',function(err,date){
        if(err){
            console.log(err.stack);
        }else{
            console.log(date.toString());
        }
    });

    4.同步读取
        var data = fs.readFileSync('input.txt');
        console.log("同步读取: " + data.toString());

    5.异步同步同时存在遵循同步有先

    6.fs.open(path,flags,mode,callback);在异步模式下打开文件
        path--文件路径
        flags--以何种方式打开r r+ rs rs+ w w+  wx wx+ a ax a+ ax+
    
    7.fs.stat(path, callback)通过异步模式获取文件信息
        fs.stat('hello.js', function (err, stats) {
            console.log(stats.isFile());         //true
        })

    8.stats 是 fs.Stats 对象,里面的方法有https://www.runoob.com/nodejs/nodejs-fs.html
            1.stats.isFile()    如果是文件返回 true,否则返回 false
            2.stats.isDirectory()    如果是目录返回 true,否则返回 false

    9.异步写入文件fs.writeFile(file, data[, options], callback)
        1.writeFile 直接打开文件默认是 w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容

        2.file - 文件名

        3.data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(流) 对象

        4.options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'

        5.callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回

    10.读取文件 
        1.异步模式下读取文件fs.read(fd, buffer, offset, length, position, callback)
            1.fd - 通过 fs.open() 方法返回的文件描述符
        
        2.示例
        var buf = new Buffer(1024);
        console.log("准备打开已经存在的文件");
        fs.open('input.txt','r+',function(err,fd){
            if(err){
                return console.error(err);
            }
            console.log('文件打开成功');
            console.log('准备开始读取文件');
            fs.read(fd,buf,0,buf.length,0,function(err,bytes){
                if(err){
                    console.log(err);
                }
                console.log(bytes + '字节被读取');
                if(bytes>0){
                    console.log(buf.slice(0,bytes).toString());
                }
            });
        });

    11.关闭文件
        1.fs.close(fd, callback)异步模式下关闭文件
            fs.close(fd, function(err){
                if (err){
                    console.log(err);
                } 
                    console.log("文件关闭成功");
            });

    12.截取文件fs.ftruncate(fd, len, callback)
        fs.ftruncate(fd, 10, function(err){
            if (err){
                console.log(err);
        } 
        console.log("文件截取成功。");

        1.fd - 通过 fs.open() 方法返回的文件描述符,截取后这个fd就不再是之前的整个fd代表的内容

        2.截取后会改变原文件变成截取的内容

    13.删除文件fs.unlink(path, callback)
        var fs = require("fs");

        console.log("准备删除文件!");
        fs.unlink('input.txt', function(err) {
            if (err) {
                return console.error(err);
            }
                console.log("文件删除成功!");
        });

    14.创建目录fs.mkdir(path[, mode], callback)
        1.mode - 设置目录权限,默认为 0777

        2.path 全文件路径
        
        3.示例
        console.log('创建的目录是/test/');
        fs.mkdir("E:/myphp/PHPTutorial/WWW/nodejsdemo/test/",function(err){
            if(err){
                return console.error(err);
            }
            console.log("目录创建成功。");
        });

    15.读取目录fs.readdir(path, callback)
        console.log("查看E:/myphp/PHPTutorial/WWW/nodejsdemo/util目录");
        fs.readdir("E:/myphp/PHPTutorial/WWW/nodejsdemo/util",function(err, files){
            if (err) {
                return console.error(err);
            }
            files.forEach( function (file){
                console.log( file );
            });
        });

    16.删除目录fs.rmdir(path, callback)

    17.fs.writeFile 并不一定是覆盖原来文件内容,而是取决于打开文件时带的 flags。如果是通过 writeFile 直接打开文件默认是 w 模式,
    但是也可以通过 open 打开文件指定模式,然后通过 writeFile 来写文件
            fs.open(fileName, "a+", function(err, fd){
            if (err) {
                return console.error(err);
            }
            fs.writeFile(fd, "bb", function(err){
                if (err){
                    return console.error(err);
                }
            });
        });

二、events模块
    1.只提供了一个对象events.EventEmitter EventEmitter是事件触发和事件监听器功能的核心
        var events = require('events');
        var eventEmitter = new events.EventEmitter();

        或者写成
        var EventEmitter = require('events').EventEmitter;
        var event = new EventEmitter();

        绑定事件监听  同一个myevent可以绑定多个执行函数执行不同的任务,触发执行的时候会依次执行
        event.on('myevent',function(){
            console.log('这个是我定义的事件');
        });

        触发事件
        event.emit('myevent');

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

        为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
        server.on('connection', function (stream) {
            console.log('someone connected!');
        });

        为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
        server.once('connection', function (stream) {
            console.log('Ah, we have our first user!');
        });

        移除指定事件的某个监听器
        var callback = function(stream) {
            console.log('someone connected!');
        };
        server.on('connection', callback);
        server.removeListener('connection', callback);

        移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器
        removeAllListeners([event])

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

        继承 EventEmitter
        大多数时候我们不会直接使用EventEmitter,而是在对象中继承他


三、Buffer类 作为nodejs处理和存储二进制数据的缓冲区 一个Buffer类似于一个整数数组
    1.创建Buffer类
        var buf1 = Buffer.alloc(size,fill,encodeing); 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0

        var buf2 = Buffer.from([1,2,3]);创建一个包含 [0x1, 0x2, 0x3] 的 Buffer

        指定大小后存入数据buf1.write('这个是要存储的字符串');

        读取里面的字符串使用buf.toString('编码格式','切取开始位置','切取结束位置');默认UTF-8编码,3个参数都是选填

    2.将Buffer转换成JSON对象buf.toJSON()
        1.当字符串转换成一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 toJSON()。
            将字符串转成JSON使用JSON.stringify(json对象)
            将JSON对象解码成字符串使用JSON.parse(json);

    3.缓冲区合并
        var buffer1 = Buffer.from(('菜鸟教程'));
        var buffer2 = Buffer.from(('www.runoob.com'));
        var buffer3 = Buffer.concat([buffer1,buffer2]);
        console.log("buffer3 内容: " + buffer3.toString());

    4.Buffer比较函数buf.compare(otherBuffer);返回值是个数字0 -1 1 返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同。

    5.拷贝缓冲区 会覆盖掉之前的,而且长度保持跟之前的一样,相当于copy加覆盖
        var buffer1 = Buffer.from(('菜鸟教程'));
        var buffer2 = Buffer.from(('www.runoob.com'));
        buffer2.copy(buffer1,从哪个位置开始覆盖,copy开始位置,copy结束位置);从buffer2复制到buffer1的哪个开始位置,copybuffer2的开始位置结束位置

    6.缓冲区剪切
        var buffer1 = Buffer.from(('www.runoob.com'));
        var buffer2 = buffer1.slice(剪切buffer1开始位置,结束位置);

    7.缓冲区的长度属性length
        var buffer1 = Buffer.from(('www.runoob.com'));
        buffer1.length

四、stream 流
    1.Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)
        1.Readable 可读
        2.Writable 可写
        3.Duplex 可读可写
        4.Transform 操作被写入数据,然后读出结果
    
    2.所有的 Stream 对象都是 EventEmitter 的实例
        1.data - 当有数据可读时触发

        2.end - 没有更多的数据可读时触发

        3.error - 在接收和写入过程中发生错误时触发

        4.finish - 所有数据已被写入到底层系统时触发
    
    3.读取流
        var fs = require('fs');
        var data = '';
        var readerStream = fs.createReadStream('url');
        readerStream.setEncoding('UTF8');
        readerStream.on('data',function(chunk){
            data += chunk;
        });

        readerStream.on('end',function(){
            console.log(data);
        });

        readerStream.on('error', function(err){
            console.log(err.stack);
        });

    4.写入流
        var fs = require('fs');
        var data = 'www.good.com';
        var writerStream = fs.createWriteStream('output.txt');
        writerStream.write(data,'UTF8');
        writerStream.end();
        writerStream.on('finish', function() {
            console.log("写入完成。");
        });
        writerStream.on('error', function(err){
            console.log(err.stack);
        });
        console.log("程序执行完毕");

    5.管道流pipe
        var fs = require("fs");

        // 创建一个可读流
        var readerStream = fs.createReadStream('input.txt');

        // 创建一个可写流
        var writerStream = fs.createWriteStream('output.txt');
        // 管道读写操作
        // 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
        readerStream.pipe(writerStream);

    6.链式流 压缩或解压一个流(诸如一个文件)可以通过管道将源数据流通过一个zlib流转化为目标流
        const zlib = require('zlib');//解压缩模块
        const gzip = zlib.createGzip();
        const fs = require('fs');
        const rs = fs.createReadStream('input.txt');
        const ws = fs.createWriteStream('input.txt.gz');
        rs.pipe(gzip).pipe(ws);

五、Node.js模块系统
    1.为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

    2.模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展

    3.简单模块
        exports.world  =function(){
            console.log('Hello World');
        }

    4.把对象封装到模块里面
        function Hello(){
            var name;
            this.setName = function(mname){
                name = mname;
            }
            this.sayHello = function(){
                console.log('Hello' + name);
            }
        }
        module.exports = Hello;

    5.引入模块的步骤
        1.开始require
        2.检查模块是否在文件模块缓存区,如果在文件模块缓存区,返回exports
        3.如果不在文件模块缓存区,检查引入的模块是不是原生模块,如果是原生模块,检查是不是在原生模块缓存区,如果在原生模块缓存区就返回exports
        4.如果不在原生模块缓存区,那就加载原生模块然后缓存原生模块
        5.如果不是原生模块那么进行查找文件模块,根据扩展名载入文件模块,缓存文件模块,返回exports

六、http模块
    1.http模块主要用于搭建HTTP服务
        var http = require('http');
        http.createServer(function(request,response){
            response.writeHead(200,{'Content-Type' : 'text/plain'});
            response.write('Hello World');
            response.end();
        }).listen(8080,'127.0.0.1');

    2.ceateServer方法接受一个函数作为参数,该函数的request参数是一个对象,表示客户端的HTTP请求;response参数也是一个对象,表示服务器端的HTTP回应。
    response.writeHead方法用来写入HTTP回应的头信息;response.end方法用来写入HTTP回应的具体内容,以及回应完成后关闭本次对话。最后的listen(8080)表示启动服务器实例,监听本机的8080端口。
    
    3.上面的例子是收到请求后生成网页,也可以事前写好网页,存在文件中,然后利用fs模块读取网页文件,将其返回。
        var http = require('http');
        var fs = require('fs');
        http.createServer(function (request, response){
        fs.readFile('data.txt', function readData(err, data) {
            response.writeHead(200, {'Content-Type': 'text/plain'});
            response.end(data);
        });

        或者
        fs.createReadStream(`${__dirname}/index.html`).pipe(response);
        }).listen(8080, '127.0.0.1');

        console.log('Server running on port 8080.');

    4.http模块参考地址https://www.cnblogs.com/mtl-key/p/6426182.html

七、url模块
    1.url.parse()可以将一个完整的URL地址,分为很多部分,常用的有:host、port、pathname、path、query。

    url示例http://localhost:8080/mm/demo.html?a=1&b=2

    var pathname = url.parse(req.url).pathname;得到mm/demo.html
    var query = url.parse(req.url).query; 得到a=1&b=2

八、querystring模块
    1.querystring.parse(query)["a"]
    2.querystring.parse(query)["b"]


八、路由
    1.路由会根据请求的URL和GET及POST参数来执行相关的对应的代码,因此,我们需要查看 HTTP 请求,从中提取出请求的 URL 以及 GET/POST 参数

    2.我们需要的所有数据都会包含在 request 对象中,该对象作为 onRequest() 回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的 Node.JS 模块,它们分别是 url 和 querystring 模块

九、Node.js 全局对象
    1.全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。

    2.global 最根本的作用是作为全局变量的宿主

    3.__filename 表示当前正在执行的脚本的文件名,输出文件所在位置的绝对路径,如果是模块那么返回模块的绝对路径

    4.__dirname 表示当前执行脚本所在的目录。

    5.全局函数setTimeout(要执行的代码,毫秒数) 延迟多少毫秒数执行,只执行一次

    6.全局函数clearTimeout(t) 用于停止之前创建的定时器,参数t是之前定时器的句柄值

    7.全局函数setInterval(要执行的代码,毫秒数) 每隔多少毫秒数执行,多次执行,不清除就不会停

    8.全局函数clearInterval(t) 函数来清除定时器,参数t是之前定时器的句柄值

    9.console 用于提供控制台标准输出
        console.log([1],[2]);//[1][2]
        console.log('byvoid%diovyb', 1991); 
        console.info("程序开始执行:");

        //time和timeEnd配合使用,参数要一致就可以获取执行时间
        console.time("1");
        //其他代码
        console.timeEnd('1');
        //效果1: 0.113ms

    10.process 是一个全局变量,即 global 对象的属性,用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口
        1.process对象的事件exit beforeExit Signal
            process.on('exit',function(code){
                //以下代码永远不会执行
                setTimeout(function(){
                    console.log('我永远也不会执行');
                },0);
                console.log('退出码为',code);//这里的退出状态码是0
            });

        2.exit退出状态码https://www.runoob.com/nodejs/nodejs-global-object.html

        3.process对象的属性 https://www.runoob.com/nodejs/nodejs-global-object.html
            1.stdout 标准输出流
                process.stdout.write("Hello World!" + "\n");
            2.stdin 标准输入流
            3.stderr 标准错误流
            4.argv argv 属性返回一个数组,由命令行执行脚本时的各个参数组成。它的第一个成员总是node,第二个成员是脚本文件名,其余成员是脚本文件的参数
                process.argv.forEach(function(val, index, array) {
                     console.log(index + ': ' + val);
                });
            5.execPath 返回执行当前脚本的 Node 二进制文件的绝对路径
                console.log(process.execPath);
            6.execArgv 返回一个数组,成员是命令行下执行脚本时,在Node可执行文件与脚本文件之间的命令行参数
            7.env 返回一个对象,成员为当前 shell 的环境变量
            8.exitCode 进程退出时的代码,如果进程优通过 process.exit() 退出,不需要指定退出码
            9.version Node 的版本
            10.versions 一个属性,包含了 node 的版本和依赖
            11.config 一个包含用来编译当前 node 执行文件的 javascript 配置选项的对象。它与运行 ./configure 脚本生成的 "config.gypi" 文件相同。
            12.pid 当前进程的进程号
            13.title 进程名,默认值为"node",可以自定义该值
            14.arch 当前 CPU 的架构
            15.platform 运行程序所在的平台系统 'darwin', 'freebsd', 'linux', 'sunos' 或 'win32'
                console.log(process.platform);

        4.process对象的其他方法
            1.abort() 这将导致 node 触发 abort 事件。会让 node 退出并生成一个核心文件

            2.chdir(directory) 改变当前工作进程的目录,如果操作失败抛出异常

            3.cwd() 返回当前进程的工作目录

            4.exit([code]) 使用指定的 code 结束进程。如果忽略,将会使用 code 0

十、Node.js 常用工具
    1.util 是一个Node.js 核心模块,提供常用函数的集合

    2.util.inherits(A,B); A继承B原型上的属性和方法

    3.util.inspect(object) 将对象转换成字符串,通常用于调试和错误输出,只是为了在控制台显示出对象

    4.util.isArray(object); 判断给定参数object是不是一个数组,返回布尔值

    5.util.isRegExp(object); 判断给定参数object是不是一个正则表达式,返回布尔值

    6.util.isDate(object);判断给定参数object是不是一个日期看是不是Date()函数的属性或者方法,返回布尔值
    
    7.util.isError(object);判断给定参数object是不是一个错误对象,返回布尔值

十一、Node.js GET/POST请求
    1.在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交

    2.表单提交到服务器一般都使用 GET/POST 请求

    3.获取GET请求内容

    4.由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数

    5.POST请求的内容都在http消息实体内,因为POST传输很可能是大文件大数据传输,如果立刻就解析的话会大量消耗服务器资源
        所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做
    
    6.示例
        var http = require('http');
        var querystring = require('querystring');
        
        http.createServer(function(req, res){
            // 定义了一个post变量,用于暂存请求体的信息
            var post = '';     
        
            // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
            req.on('data', function(chunk){    
                post += chunk;
            });
        
            // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
            req.on('end', function(){    
                post = querystring.parse(post);
                res.end(util.inspect(post));
            });
        }).listen(3000);

    7.实例表单通过 POST 提交并输出数据详细看post.js

十二、querystring模块
    1. const querystring = require("querystring");

    2.querystring方法介绍
        1.querystring.parse(str);将一个字符串反序列化为一个对象
        2.querystring.stringify(obj)将一个对象序列化成一个字符串
        3.querystring.escape(str)使传入的字符串进行编码
        4.querystring.unescape(str)将含有%的字符串进行解码

十三、Node.js工具模块
    1.OS模块 提供基本的系统操作函数https://www.runoob.com/nodejs/nodejs-os-module.html

    2.var os = require("os")

    3.Path模块 提供了处理和转换文件路径的工具 https://www.runoob.com/nodejs/nodejs-path-module.html

    4.var path = require("path")

    5 转换为绝对路径path.resolve('main.js')
        console.log('resolve : ' + path.resolve('main.js'));

    6.Net模块
        1.提供了一些用于底层的网络通信的小工具,包含了创建服务器/客户端的方法

        2.var net = require("net")

        3.net.Server通常用于创建一个 TCP 或本地服务器

        4.net.Socket对象是 TCP 或 UNIX Socket 的抽象。net.Socket 实例实现了一个双工流接口。 他们可以在用户创建客户端(使用 connect())时使用, 或者由 Node 创建它们,并通过 connection 服务器事件传递给用户

    7.DNS模块 用于解析域名
        1.var dns = require("dns")

        2.dns.lookup('url',function onLookup(err,address,family){});

        3.dns.reverse(address,function(err,hostnames){});

    8.Domain模块 域 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常
        1.隐式绑定: 把在domain上下文中定义的变量,自动绑定到domain对象
            // 隐式绑定
            domain2.run(function(){
            var emitter2 = new EventEmitter();
            emitter2.emit('error',new Error('通过 domain2 处理'));   
            });

        2.显式绑定: 把不是在domain上下文中定义的变量,以代码的方式绑定到domain对象
            var EventEmitter = require("events").EventEmitter;
            var domain = require("domain");

            var emitter1 = new EventEmitter();

            // 创建域
            var domain1 = domain.create();

            domain1.on('error', function(err){
            console.log("domain1 处理这个错误 ("+err.message+")");
            });

            // 显式绑定
            domain1.add(emitter1);

            emitter1.on('error',function(err){
            console.log("监听器处理此错误 ("+err.message+")");
            });

            emitter1.emit('error',new Error('通过监听器来处理'));

            emitter1.removeAllListeners('error');

            emitter1.emit('error',new Error('通过 domain1 处理'));

            var domain2 = domain.create();

            domain2.on('error', function(err){
            console.log("domain2 处理这个错误 ("+err.message+")");
            });


十四、express框架 
    1.Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具

    2.Express 框架核心特性
        1.可以设置中间件来响应 HTTP 请求
        2.定义了路由表用于执行不同的 HTTP 请求动作
        3.可以通过向模板传递参数来动态渲染 HTML 页面

    3.Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性

    4.Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据

    5.Express 提供了内置的中间件 express.static 来设置静态文件如:图片, CSS, JavaScript

    6.如果借助了中间件express.static('public') 请求的图片,css,js应该存放在public文件夹里面

    7.app.use(express.static('public'));

    8.express的应用
        1.get中的response request 响应请求
            var express = require('express');
            var app = express();
            
            app.get('/', function (req, res) {
            res.send('Hello World');
            })
            
            var server = app.listen(8081, function () {
            
            var host = server.address().address
            var port = server.address().port
            
            console.log("应用实例,访问地址为 http://%s:%s", host, port)
            
            })

        2.路由 通过路由提取出请求的URL以及GET/POST参数决定了由谁(指定脚本)去响应客户端请求
            var express = require('express');
            var app = express();
            
            //  主页输出 "Hello World"
            app.get('/', function (req, res) {
            console.log("主页 GET 请求");
            res.send('Hello GET');
            })
            
            
            //  POST 请求
            app.post('/', function (req, res) {
            console.log("主页 POST 请求");
            res.send('Hello POST');
            })
            
            //  /del_user 页面响应
            app.get('/del_user', function (req, res) {
            console.log("/del_user 响应 DELETE 请求");
            res.send('删除页面');
            })
            
            //  /list_user 页面 GET 请求
            app.get('/list_user', function (req, res) {
            console.log("/list_user GET 请求");
            res.send('用户列表页面');
            })
            
            // 对页面 abcd, abxcd, ab123cd, 等响应 GET 请求
            app.get('/ab*cd', function(req, res) {   
            console.log("/ab*cd GET 请求");
            res.send('正则匹配');
            })
            
            
            var server = app.listen(8081, function () {
            
            var host = server.address().address
            var port = server.address().port
            
            console.log("应用实例,访问地址为 http://%s:%s", host, port)
            
            })
        
        3.中间件express.static('public') 请求的图片,css,js应该存放在public文件夹里面
            var express = require('express');
            var app = express();
            
            app.use(express.static('public'));
            
            app.get('/', function (req, res) {
            res.send('Hello World');
            })
            
            var server = app.listen(8081, function () {
            
            var host = server.address().address
            var port = server.address().port
            
            console.log("应用实例,访问地址为 http://%s:%s", host, port)
            
            })

            http://127.0.0.1:8081/images/logo.png

        4.文件上传

        5.Cookie 管理  使用中间件向 Node.js 服务器发送 cookie 信息
            var express = require('./express/index.js');
            var app = express();
            var cookieParser = require('./cookie-parser/index.js')
            var util = require('util');
            
            var app = express()
            app.use(cookieParser())
            
            app.get('/', function(req, res) {
                console.log("Cookies: " + util.inspect(req.cookies));
            })
            
            app.listen(8081)

十五、Node.js RESTful API
    1.REST即表述性状态传递(英文:Representational State Transfer,简称REST)

    2.RESTful是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful 只是遵循REST架构的设计风格,不是标准,

    3.Web Services 平台独立的,低耦合的,自包含的、基于可编程的web的应用程序

    4.REST 通常使用 JSON 数据格式

    5.示例见REST文件夹


十六、Node.js 多进程
    1.Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能

    2.每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象

    3.Node 提供了 child_process 模块来创建子进程
        1.exec - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回
            const fs = require('fs');
            const child_process = require('child_process');
            
            for(var i=0; i<3; i++) {
                var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
                    if (error) {
                        console.log(error.stack);
                        console.log('Error code: '+error.code);
                        console.log('Signal received: '+error.signal);
                    }
                    console.log('stdout: ' + stdout);
                    console.log('stderr: ' + stderr);
                });
            
                workerProcess.on('exit', function (code) {
                    console.log('子进程已退出,退出码 '+code);
                });
            }        
        2.spawn - child_process.spawn 使用指定的命令行参数创建新进程
            const fs = require('fs');
            const child_process = require('child_process');
            
            for(var i=0; i<3; i++) {
            var workerProcess = child_process.spawn('node', ['support.js', i]);
            
            workerProcess.stdout.on('data', function (data) {
                console.log('stdout: ' + data);
            });
            
            workerProcess.stderr.on('data', function (data) {
                console.log('stderr: ' + data);
            });
            
            workerProcess.on('close', function (code) {
                console.log('子进程已退出,退出码 '+code);
            });
            }
        3.fork - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['./son.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信
            const fs = require('fs');
            const child_process = require('child_process');
            
            for(var i=0; i<3; i++) {
            var worker_process = child_process.fork("support.js", [i]);    
            
            worker_process.on('close', function (code) {
                console.log('子进程已退出,退出码 ' + code);
            });
            }
        4.exec()方法 child_process.exec(command[, options], callback) 使用子进程执行命令

        5.process.argv返回命令行脚本的各个参数组成的数组


十七、Node.js JXcore 打包
    1.Node.js 是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境

    2.JXcore 是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行
    
    3. JXcore 的打包功能
        1.下载安装包解压后配置环境变量

        2.进入需要打包的文件夹

        3.选择需要打包的文件jx package index.js index

        4.执行后产生2个文件index.jx index.jxp
            1.index.jxp 这是一个中间件文件,包含了需要编译的完整项目信息
            2.index.jx 这是一个完整包信息的二进制文件,可运行在客户端上
            
        5.使用 JXcore 编译后,我们可以使用以下命令来执行生成的 jx 二进制文件 运行命令jx index.jx
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值