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


    1.Node.js是什么
    Node.js是一个让JS运行在服务器端的开发平台,它可以作为服务器向用户提供服务。Node.js中的
    javascript只是Core javascript,或者说是ECMAJavaScript的一个实现。
    2.Node.js能做什么
    JS是为客户端为生,而Node.js是为网络而生。利用它可以轻松的开发出很多网站、社交应用、服务
    器等等。
    Node.js内建有一个HTTP服务器支持,可以实现一个网站和服务器的组合。
    3.异步式I/O和事件驱动
    Node.js最大的特点就是采用异步式I/O和事件驱动的架构设计。对于所有I/O都采用异步式的请求方
    式,避免了上下文切换所带来的耗费系统资源、死锁、同步、低速连接攻击等问题。Nodejs在执行的过程中会维护一个事件队列,程序在执行时进入事件循环等待下一个事件的带来。每个异步式IO请求完成以后会被推送到事件队列,等待程序进程进行处理。 Node.js进程在同一时刻只会处理一个事件,完成以后立
    即进入事件循环检查并处理后面的事件。这样,CPU和内存同一时刻只会处理一个事件并且尽可能让耗时的I/O操作并行执行。
    缺点就是不符合传统开发者的变成思维,往往需要把一个完整的逻辑拆分成为一个个事件,增加了开
    发和调试难度。
    4.console.log()相当于C的printf(),也可以接受任意个参数,支持%d,%s的变量引用
    eg: console.log('%s:%d','hello',25);
    // hello:25
    // undefined(这个是返回值 )
    5.在终端输入node 回车 便可以进入REPL模式 可以直接写入JS代码运行
    6.与传统服务器语言不同的是(以PHP为例)
    浏览器--HTTP服务器--PHP解释器
    而Node.js直接将服务器抽离,直接面向浏览器用户
    浏览器--Node
    7.创建一个http服务器
    //app.js

    var http = require('http'); //调用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); //监听3000端口号

    console.log("HTTP server is listening at port 3000.");
    在终端运行 node app.js(注意要找到当前目录下)
    会发现现在NOED一直在等待,进程不会退出事件循环。就无法实现实时刷新页面,不利于调试,因此可以安装一个模块supervisor
    eg:$npm install -g supervisor
    退出CTRL+C当前栈,运行 supervisor app.js
    当代码改动的时候,运行的脚本被停止,然后重新启动,刷新页面,就可以看到实时刷新的数据。
    8.阻塞与线程
    1.同步式I/O(阻塞式I/O)
    线程在执行中如果遇到磁盘读写或网络通信,通常要耗费较长时间。这时OS会剥夺这个线程的CPU控制权,使其暂停执行。同时将资源让给其他的工作线程,这种线程调度方式称之为阻塞,当I/O操作完毕时,OS将这个线程的阻塞状态解除,回复CPU对其的控制权,令其继续执行。
    1.异步式读取文件
    var fs = require('fs'); //请求FS模块
    fs.readFile('file.txt','utf-8',function(err,data){ //读取文件
    (当前目录/指定目录下的文件名 文件格式 回调函数(错误,文件里的数据))
    if(err){
    console.log(err);
    }else{
    console.log(data);
    }
    });
    console.log('end');
    可以看到先打印end然后在打印err或者data;
    2.同步式读取文件
    var fs = require('fs');
    fs.readFileSync('file.txt','utf-8',function(err,data){//选择同步模式读取文件
    if(err){
    console.log(err);
    }else{
    console.log(data);
    }
    });
    可以看到先打印err或者data再打印end

    2.异步式I/O(非阻塞式I/O)
    针对所有I/O操作不采用阻塞策略,当线程遇到I/O操作时,只是把请求发送给OS,继续执行下一条语句,当OS完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程在特定的时候处理这个事件。因此,node有事件循环机制,不断的检查有没有未处理的事件,依次进行处理。
    3.二者区别:
    非阻塞模式下,一个线程永远在执行计算操作,CPU利用率为100%,I/O以事件的形式通知。
    阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞还有其他线程。
    具体:
    同步式I/O 异步式I/O
    利用多线程提高吞吐量 单线程可实现提高吞吐量
    通过事件片分割和线程调度利用多核CPU 通过功能划分利用多核
    需要操作系统调度多线程使用多核CPU 可以将单线程绑定到单核CPU
    难以充分利用CPU资源 充分利用CPU资源
    内存轨迹大,数据局部性弱 内存轨迹小,数据局部性强
    符合线性的编程思维 不符合传统变成思维
    4.在node环境下可以直接运行JS代码
    比如:node //进入node环境
    Console.log(‘NEVER GIVE UP’);//在终端上打印出NEVER GIVE UP
    //第二行undefined是返回值
    PS:不能用alert,因为alert是window下的一个方法
    或者运行JS文件
    比如hello.js文件
    直接 node hello.js便可以执行

    9.Node所有的异步I/O操作在完成时都会发送一个事件到事件队列。然后通过轮询机制触发事件。
    //event.js

    var EventEmitter = require('events').EventEmitter;//请求事件对象
    var event = new EventEmitter(); //实例化对象

    event.on('some_event', function() { //注册事件some_event的一个监听器
    console.log('some_event occured.');
    });

    setTimeout(function() { //1000MS后向event对象发送事件
    event.emit('some_event');
    }, 1000);
    2.事件的循环机制
    1.node.js程序是由事件循环开始,到事件循环结束。所有的逻辑都是基于事件的回调函数
    2.事件的回调函数在执行的过程中,可以能会发出I/O请求或者直接触发(emit)事件,执行完毕以后再返回事件循环。事件循环会检查事件队列中有没有未处理的事件,直
    到检测不到时才退出事件循环,进程结束。
    10.模块和包是NODE最重要的支柱。开发一个具有一定规模的程序不可能只用一个文件,通常需要把各个功能拆分、安装,然后组合起来,模块证实为了实现这种方式而诞生。包和模块本质上没有区别,只不过包是由多个模块组成,是在模块基础上提供更高层的抽象。
    //module.js
    1.加载模块
    var name;
    exports.setName = function(thyName) { //将setName暴露给外界
    name = thyName;
    };
    exports.sayHello = function() { //将sayHello暴露给外界
    console.log('Hello ' + name);
    };
    //getmodule.js

    var myModule = require('./module');//请求加载module.js这个模块

    myModule.setName('Andy'); //调用module.js里面的方法
    myModule.sayHello();
    最终输出Hello Andy
    2.单次加载
    var myModule1 = require('./module');
    myModule.setName('Andy');

    var myModule2 = require('./module');
    myModule.setName('King');

    myModule.sayHello();//Hello King
    因为他们指向了同一个实例,myModule1被myModule2覆盖
    3.覆盖exports
    function Hello() {
    var name;

    this.setName = function (thyName) {
    name = thyName;
    };

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

    exports.Hello = Hello; //前Hello是一个暴露属性给外界 后面的hello是指 function Hello
    这样想获取hello对象就需要require('./filename').Hello来获取hello对象
    !麻烦。
    如果最后一行这样引用module.exports = Hello;这样只要var Hello = require('./hello');就
    可以了.
    注意:在外部引用该模块时,其接口对象就是要输出Hello对象本身,而不是原先的expots.
    exports本身一个普通的空对象{},专门用于声明接口,可以用其他东西来代替,譬如Hello对象。但是i不可以通过对exports直接复制代替module.exports赋值,虽然他们指向同一个变量,但是
    exports本身会在模块执行结束以后释放,module不会,因此只能通过module.exports来改变接口。

    11.node debug XXX.js可以进入debug调试
    node --debug[=port] script.js
    node --debug-brk[=port] script.js可以进入远程调试 默认端口为5858

  • 相关阅读:
    Silverlight的依赖属性与附加属性(五)
    Silverlight Behavior技术(三)
    JQuery EasyUI 简单的左右布局左边Tree右边区域打开tab右键菜单实现 Murray
    使用Areas分离ASP.NET MVC项目(前后台以及对应功能模块) Murray
    IDisposable 接口 Murray
    MVC3/4 自定义HtmlHelper截断文本内容 Murray
    30个最常用css选择器解析(经典) Murray
    asp.net 中使用 SqlBulkCopy 将一个目录下指定类型的数据文件导入到数据库 Murray
    EntityState 枚举的5中状态的变化 Murray
    IEnumerable<T> 接口主要成员 Murray
  • 原文地址:https://www.cnblogs.com/zhouqi666/p/5482826.html
Copyright © 2020-2023  润新知