• NODE.JS开发指南学习笔记2


    1.核心模块
    核心模块是Node.js的心脏,由一些精简高效的库组成,为其提供了基本的API。
    2.全局对象
    global。所有的的全局变量都是其属性。其根本的作用是作为全局变量的宿主。
    3.全局变量
    1.process:描述当前Node.js的进程状态的对象,提供一个与操作系统的简单接口。
    方法 process.argv 命令行参数数组 三个参数1.node 2.脚本文件名 3.运行参数
    1.process.stdout: 标准输出流,通常使用的console.log()向标准输出打印字符,而process.stdout.write提供了更底层的接口。
    2.process.stdin:标准输入流 初始状态为暂停 要想从标准输入读取数据,必须恢复流,并手动
    编写流的事件相应函数。
    process.stdin.resume(); //回复流

    process.stdin.on('data', function(data) {//监听事件相应
    process.stdout.write('read from console: ' + data.toString());//返回输入内容
    });
    在终端输入 Andy
    在终端输出 read from console:Andy
    如果不退出CTRL+C 事件将一直处于相应状态

    3.process.nextTick(callback):为事件循环设置一项任务,Node.js会在下次事件循环响应时调
    用callback;
    PS:因为NODE.JS进程只有一个线程,因此在任何时刻都只有一个事件在执行,如果这个事件
    占用大量CPU时间,执行事件循环中的下一个事件就需要等待很久,因此NODE.JS的一个原则
    是尽量缩短每个事件的执行时间。process.nextTick提供了一个这样的工具,可以把复杂的
    工作拆散,变成一个个较小的事件。
    function a(args, callback) {
    b(args);
    callback();
    }

    a(function c() {
    d();
    });
    假设a,b是两个耗时的程序。
    执行流程:1.执行a,把c当作参数传给args
    2.执行b,这里的参数为函数c
    3.执行c
    4.执行d
    5.执行回调
    用process.nextTick改写
    function doSomething(args, callback) {
    somethingComplicated(args);
    process.nextTick(callback);
    }

    doSomething(function onEnd() {
    compute();
    });
    改写后的程序会把上面耗时的操作拆分为两个事件,减少每个事件的执行时间,提高事件相应速度。不要使用setTimeout(fn,0)代替,因为这个效率要低的多。
    4.其他看API文档
    2.console:用于向标准输出流或者标准错误流输出字符
    1.console.log() 向标准输出流打印字符并以换行符
    2.console.error() 向标准错误流输出字符并以换行符
    3.console.trace() 向标准错误流输出当前的调用栈
    4.常用工具
    1.util:核心模块,提供常用的函数集合。
    1.util.inherits(constructor,superConstructor)是一个实现对象间原型继承的函数。子类继
    承超类。JS中没有提供对象继承的语言级别特性,而是通过原型复制来实现的。
    var util = require('util'); //请求模块

    function Base() { //Base构造函数
    this.name = 'base';
    this.base = 1991;

    this.sayHello = function() {
    console.log('Hello ' + this.name);
    };
    }

    Base.prototype.showName = function() {//原型方法showName
    console.log(this.name);
    };

    function Sub() { //Sub构造函数
    this.name = 'sub';
    }

    util.inherits(Sub, Base); //Sub继承Base的原型

    var objBase = new Base(); //实例化
    objBase.showName(); //base
    objBase.sayHello(); //Hello base
    console.log(objBase); //Base{name:'base',base:1991,sayHello:[function]}
    //原型属性不会被console.log()作为对象的属性输出


    var objSub = new Sub();
    objSub.showName(); //Sub
    objSub.sayHello(); //报错 因为Sub只是继承Base的原型,sayHello不在原型
    console.log(objSub); Sub{name:'sub'}
    2.util.inspect(object,[showhidden],[depth],[colors])是一个将任意对象转换为字符串的方法,
    通常用于调试和错误输出。
    参数:唯一的必选参数 object :要转换的对象
    showhidden 默认为false 如果为true 将会输出更多信息
    depth 表示递归的最大层数 默认为2层 null为无限制
    colors 如果值为true 输出格式将会以ANSI颜色编码,更漂亮
    3.其他查API文档
    5.事件驱动events:最重要的模块,没有之一,是NODE.JS编程的基石。不仅用于用户代码与node.js下
    层事件循环的交互,还几乎被所有的模块依赖。
    1.events模块只提供一个对象:events.EventEmitter
    1.events.EventEmitter:事件发射与事件监听器功能的封装。
    events.EventEmitter的每个事件由一个事件名和若干参数组成。对于每个事件,支持若干
    个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为
    回调函数参数传递。
    var events = require('events'); //请求模块

    var emitter = new events.EventEmitter(); //实例化对象

    emitter.on('someEvent', function(arg1, arg2) { //监听someEvent
    console.log('listener1', arg1, arg2); //执行回调
    });

    emitter.on('someEvent', function(arg1, arg2) { //监听someEvent
    console.log('listener2', arg1, arg2); //执行回调
    });

    emitter.emit('someEvent', 'byvoid', 1991); //触发事件

    events.EventEmitter常用API
    1.EventEmitter.on(event,callback);
    为指定事件注册一个监听器,接受一个字符串(事件名) 和一个回调函数
    2.EventEmitter.emit(event,[arg1],[arg2],[arg3]……);触发事件event,
    并传入若干参数到事件监听器的参数表
    3.EventEmitter.once(event,callback) 与on不同的是最多触发一次,触发后
    立即解除该监听器。
    4.EventEmitter.removeListener(event,Listener)移除指定事件的某个监听
    器,Listener必须是该事件已经注册过的监听器。
    5.EventEmitter.removeALLListener([event]);移除所有事件的所有监听器,
    如果指定event,则移除指定事件的所有监听器。
    6.error 当error被发射时,EventEmitter规定如果没有响应的监听器,NODE.JS会把它当作异常,退出程序并打印调用栈。我们一般要为会发射error时间的对象设置监听器。避免遇到错误后整个程序崩溃。
    var events = require('events');

    var emitter = new events.EventEmitter();

    emitter.emit('error');
    PS:大多时候不会直接使用EventEmitter,而生在对象中继承它,包括FS, .NET, HTTP,
    只要支持事件相应的模块的核心模块都是EventEmitter的子类。
    原因1:具有某个实体功能的对象实现事件符合语义,事件的监听和发射应该是一个对象的方法。
    2:JS是基于原因支持部分多重继承,继承EventEmitter不会打乱对象原有的继承关系。
    2.文件系统FS
    FS模块是文件操作的封装,它提供了文件的读取、写入、更名、删除、遍历目录、连接等POSIX
    文件系统操作。FS所有的操作都提供的同步和异步两个版本。
    1.fs.readFile(fileName,[encoding],[callback(err,data)]).
    唯一的一个必选参数 fileName 要读取的文件名
    encoding 文件的字符编码
    callback 回调函数
    两个参数1.err 表示有没有错误发射
    2.data 文件内容 如果指定encoding,data为解析后的字符串,否则将会以
    buffer形式表示的二进制数据。
    var fs = require('fs');

    fs.readFile('content.txt', function(err, data) {
    if (err) {
    console.error(err);
    } else {
    console.log(data);
    }
    });
    //二进制形式输出
    var fs = require('fs');

    fs.readFile('content.txt', 'utf-8', function(err, data) {
    if (err) {
    console.error(err);
    } else {
    console.log(data);
    }
    });
    //UTF编码形式输出

    NODE.JS通常有且只有一个回调函数。回调函数中第一个参数实际上是error,其余的参数
    是其他返回的内容,如果没有错误发生error值为null或者undefined。如果有错误,error通常是error对象的实例。
    2.同步:fsreadFileSync(fileName,[callback(err,filedata)])
    3.fs.open(path,flags,[mode],[callback(err,filedata)])是POSIX open函数的封装。
    必选两个参数 path为文件的路径
    flags可以是以下值
    r 只读
    r+ 读写
    w 只写,不存在则创建。
    w+ 读写,不存在则创建。
    a 追加模式打开,不存在则创建。
    a+ 以读取追加模式打开,不存在则创建。
    mode用于创建文件时给文件指定权限 默认 0666
    4.fs.read(fd,buffer,offset,length,position,[callback[err,bytesRead,buffer]])
    是POSIX read函数的封装.实现从指定的文件描述符fd 中读取数据并写入buffer指向的缓冲区
    对象。offset为buffer给入的偏移量。length是要从文件中读取的字节数。position是文件读取的起始位置,如果为null,则从当前文件指针的位置读取。回调函数传递的bytesRead,buffer分表表示读取的字节数和缓冲区对象。
    var fs = require('fs');

    fs.open('content.txt', 'r', function(err, fd) {//以只读方式打开文件
    if (err) {
    console.error(err);
    return;
    }

    var buf = new Buffer(8);
    fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) {
    if (err) {
    console.error(err);
    return;
    }

    console.log('bytesRead: ' + bytesRead);
    console.log(buffer);
    })
    });
    一般来说,没有必要采取这样的方法,很麻烦。
    5.其他API看文档。
    6.http服务器
    1.http.Server是http模块中http服务器对象,用node.js所有基于http协议的系统。提供仅仅是流控制和简单的消息解析,所有高层功能都要通过它的接口来实现,
    //httpserver.js

    var http = require('http'); //

    http.createServer(function(req, res) { //创建服务器
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write('<h1>Node.js</h1>');//响应体
    res.end('<p>Hello World</p>');//结束并发送
    }).listen(3000);//监听端口号

    console.log("HTTP server is listening at port 3000.");
    1.request,当客户端请求到来时,触发该事件。提供两个参数 req,res,
    分别是http.ServerRequest和http.ServerResponse的实例,表示请求和响应信息。
    2.connection: 当TCP连接简历时,该事件被触发,提供一个参数socket,为net.socket的实例
    。connection的粒度要大于request,因为客户端在Keep-Alive的模式下可能会在同一个连接内
    多次请求。
    3.close:当服务器关闭时,该事件被触发。注意不是在用户连接断开时。
    4.其他 checkContinue、upgrade、clientError等等
    最常用的request,http创建了一个捷径。http.createServer([requestListener]),创建一个
    http服务器并将requestListener作为request事件的监听函数。
    上面的代码实际是
    //httpserver.js

    var http = require('http');

    var server = new http.Server();
    server.on('request', function(req, res) {//注册请求事件
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write('<h1>Node.js</h1>');
    res.end('<p>Hello World</p>');
    });
    server.listen(3000);

    console.log("HTTP server is listening at port 3000.");
    2.http.ServerRequest:HTTP请求的信息。由http.Server的request事件发送,作为第一个参数传递
    ,http请求一般可以分为两部分:请求头(RequestHeader)和请求体(RequestBody).
    由三个事件用于控制请求体传输:
    1.data:当请求体数据带来时,触发事件。该事件提供一个参数chunk,表示接受的数据,
    如果该事件没有被监听,那么请求体将会被抛弃,该事件可以被调用多次。
    2.end:当请求体数据传输完成时,该事件被触发,以后将不会再有数据到来
    3.close:用户当前请求结束时,触发事件,不同于end,如果用户强制终止了传输,也会调用close。
    4.其他属性看API文档
    3.获取GET请求内容
    由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括?后面的部分,因此可以手动解析后面的内容作为GET请求的参数。 URL模块中parse函数提供这个功能。
    //httpserverrequestget.js

    var http = require('http'); //请求需要的模块
    var url = require('url');
    var util = require('util');

    http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(util.inspect(url.parse(req.url, true))); //!!
    }).listen(3000); //在localhost:3000输入路径
    以localhost:3000/uesr?name=Andy&email=445864742@qq.com为例:
    返回:{
    search:'?name=Andy&email=445864742@qq.com',
    query:{name:'Andy',email:'445864742@qq.com'}, //GET请求的内容
    pathname:'/user',
    path:'/uesr?name=Andy&email=445864742@qq.com',
    href:'/uesr?name=Andy&email=445864742@qq.com'
    }
    4.获取POST内容
    POST请求的内容全部都在请求体中。
    //httpserverrequestpost.js

    var http = require('http');
    var querystring = require('querystring');
    var util = require('util');

    http.createServer(function(req, res) {
    var post = ''; //定义一个post用于暂存请求体内容

    req.on('data', function(chunk) {
    post += chunk;
    });

    req.on('end', function() {
    post = querystring.parse(post);
    res.end(util.inspect(post));
    });

    }).listen(3000);
    通过req的data事件监听函数,每当接收到请求体的数据,就累加到post中。在end触发以后,
    通过querystring.parse将post解析为真正的post数据,然后向客户端返回。(实际项目中不能
    这么用,因为由严重的效率和安全问题);
    5.http.ServerResponse:返回给客户端的信息,决定了用户最终能看到的结果。它也是由
    http.Server的request事件发送的,作为第二个参数传递,简称为response或者res.
    三个参数
    1.response.writeHead(statusCode,[headers]):向请求的客户端发送响应头。
    statusCode是HTTP状态码
    200:请求成功
    404:未找到
    等等
    headers:一个类似关联数组的对象,表示响应头的每个属性。该函数在一个请求内最多能使用一次,如果不调用则自动生成一个响应头。
    2.response.write(data,[encoing]):向请求的客户端发送响应内容。
    data是一个buffer或字符串,表示要发送的内容。
    如果data是字符串,那么就需要指定encoding来表明编码方式,默认为UTF-8
    在调用response.end之前,可以多次调用response.write
    3.response.end([data],[encoding]):结束响应,告知客户端所有发送都已经完成。当
    所有要返回的内容发送完毕的时候,该函数 必须 被调用一次。两个可选参数如果要写的
    话用法同data
    6.HTTP客户端
    http模块提供了两个函数http.request和http.get,功能是作为客户端向HTTP服务器发起请求
    http.request(options,callback)发起http请求。
    options :一个类似关联数组的对象,表示请求的参数
    常用参数
    host:请求网站的域名或者IP地址
    port:请求的端口,默认为80
    method:请求方法,默认为GET
    path:请求的相对于根的路径,默认是/。
    headers:一个类似关联数组的对象,请求的头内容
    callback:请求的回调函数
    传递一个参数,为http.ClientRespongse的实例
    http.request返回一个http.ClientRespongse的实例。
    //httprequest.js

    var http = require('http');
    var querystring = require('querystring');

    var contents = querystring.stringify({ //将对象转换成字符串
    name: 'byvoid',
    email: 'byvoid@byvoid.com',
    address: 'Zijing 2#, Tsinghua University',
    });

    var options = {
    host: 'www.byvoid.com',
    path: '/application/node/post.php',
    method: 'POST',
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length' : contents.length
    }
    };

    var req = http.request(options, function(res) {
    res.setEncoding('utf8');
    res.on('data', function (data) {
    console.log(data);
    });
    });

    req.write(contents);
    req.end(); //这个必须有

    1.http.get(options,callback) http.request的简化版,区别在于http.get自动
    将请求方法设为了GET请求,也不需要设置req.end();
    1.http.ClientRequest是由http.request和http.get返回产生的对象,表示一个已经产生
    而且正在进行http请求。提供一个response事件,即http.get或者http.request,第二个参数时指定的回调函数的绑定对象,我们可以显式地绑定这个事件的监听函数。
    //httpresponse.js

    var http = require('http');

    var req = http.get({host: 'www.byvoid.com'});

    req.on('response', function(res) {
    res.setEncoding('utf8');
    res.on('data', function (data) {
    console.log(data);
    });
    });
    http.ClientRequest提供了write和end函数,用于向服务器发送请求体,通常用于post,和
    put等操作。结束之后必须用end
    request.abort():终止发送的请求
    request.setTimeout([callback],timeout)
    还有其他参数看API
    2.http.ClientResponse
    提供三个事件 data 数据到达时触发 一个参数chunk表示接收到的数据
    end 传输结束时触发
    close连接结束时触发
    http.ClientResponsed的一些属性用于表示请求的结果状态
    statusCode 200、404、500等
    httpVersion 协议版本
    headers HTTP请求头
    trailers 请求尾
    http.ClientResponsed的的特殊函数
    response.setEncoding
    response.pause 暂停接收数据和发送事件,方便下载
    response.resume 从暂停状态中恢复

  • 相关阅读:
    DJANGO入门系列之(模型层:跨表操作)
    DJANGO入门系列之(模型层:单表操作)
    DJANGO入门系列之(模板层)
    DJANGO入门系列之(视图层)
    DJANGO入门系列之(模板层的简单介绍和视图层的扫尾)
    DJANGO入门系列之(虚拟环境的配置与安装)
    Django入门系列之(视图层基本概念)
    DJANGO入门系列之(路由控制)
    DJANGO入门系列之(Django请求生命周期and路由层)
    orm
  • 原文地址:https://www.cnblogs.com/zhouqi666/p/5482828.html
Copyright © 2020-2023  润新知