• 初识node.js


    一、概念类

    1、node.js是什么

    node.js不是一种独立的语言,与php既是语言也是平台不同,也不是JavaScript的框架,更不是浏览器的库。node.js是一个让JavaScript运行在服务端的开发平台。

    2、node.js能做什么

    JavaScript是由客户端而产生,node.js为网络而生

    具有复杂逻辑的网站

    基于社交网站的大web的应用

    web scoket服务器

    TCP/UDP套接字应用程序

    命令行工具

    交互式终端程序

    3、异步式I/O与事件驱动

    node.js最大的特性就是采用异步式I/O与事件驱动的架构设计。对于高并发的解决方案,传统的架构是多线程模型,也就是为每个业务逻辑提供一个系统线程,通过系统线程切换来弥补同步式I/O调用时的事件开销。node.js使用的单线程模型,在执行的过程中会维护一个事件队列,程序在执行时在进入时间循环等待下一个事件到来。

    普通:res = db.query("select * form user")

         res.output();

    node.js: res = db.query("select * form user",function(res){

          res.output();

           })

    程序会自动往下执行

    4、浏览器引擎革命

    Google chrome的引擎是V8,node.js的引擎引用的就是V8,所以它快

    5、部署node.js的环境

    node.js官方,http://nodejs.org 下载安装包,安装后,打开cmd的的dos窗口,运行node

    二、node入门

    1、Hello World

    打开一个文本编辑器,其中输入console.log("Hello World"),并保存为test.js

    打开dos窗口进入该文件的目录运行 node test.js,执行则可以看到输出的Hello World

    2、node.js命令行工具

    node -v  输出版本号

    node -e  eval script  eval("console.log('哈哈')")  例:node -e "console.log('哈哈')";直接执行

    node  直接进入编译模式  console.log("111")  第一行是输出,第二行是返回值

    3、建立HTTP服务器

    建立一个app.js

    1 var http = require("http");
    2 http.createServer(function(req,res){
    3    res.writeHead(200,{'Content-Type':'text/html'});
    4    res.write('<h1>Node.js</h1>');
    5    res.end('<p>PCAT</p>');   
    6 }).listen(3000);
    7 console.log('HTTP server is listening at port 3000');

    接下来,node app.js  打开浏览器访问http://localhost:3000即可,这样就部署了一个web

    4、调试代码

    npm install supervisor -g(在nodejs ode_modules pm目录下)安装supervisor来控制调试代码,不需要每次停止重启node.js的服务

    使用supervisor app.js启动

    三、node.js异步式IO与事件式编程

    node.js最大的特性就是异步式I/O与事件紧密结合的编程模式。这种模式与传统的同步式IO线性的编程思路有很大的不同,因为控制流很大程度上要靠事件和回调函数来组织,一个逻辑要拆分为若干个单元格

    1、同步式I/O或阻塞式I/O

    线程在执行中如果遇到磁盘读写或网络通信,通常要耗费较长时间。这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时把资源让给其他的工作线程这种线程调度方式称为阻塞,当I/O操作完毕时,操作系统将这个线程的阻塞状态解除,回复其对CPU的控制权,令其继续执行

    2、异步式I/O或阻塞式I/O

    针对所有I/O操作不采用阻塞策略,当线程遇到I/O操作时,不会以阻塞的方式等待I/O操作的完成或数据的返回,二只是将IO请求发送给操作系统,继续执行下一条语句,当操作系统完成IO操作时,以事件的形式通知执行IO操作的线程,线程会在特定时候处理这个事件,为了处理异步IO,线程必须有事件循环,不断地检查有没有未处理的时间,依次予以处理

    3、非阻塞和阻塞模式的区别

    非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的CPU核心利用率永远是100%,IO以事件的方式通知

    阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞还有其他线程在工作,多线程可以让CPU资源不被阻塞中的线程浪费

    4、同步式IO与异步式IO的区别

    同步式IO(阻塞式)

    利用多线程提供吞吐量

    通过事件片分隔和线程调度利用多核CPU

    需要由操作系统调度多线程使用多核CPU

    难以充分利用CPU资源

    内存轨迹大,数据局部性弱

    符合线性的编程思维

    异步式IO(非阻塞)

    单线程即可实现高吞吐量

    通过功能划分利用多核

    可以将但相处绑定到单核CPU

    可以充分利用CPU资源

    内存轨迹小,数据局部性强

    不符合传统编程思维

     四、回调函数与事件

    1、回调函数

    1.1、异步式读取文件

    1 var fs = require("fs");
    2 var data = fs.readFile("file.txt","UTF-8",function(err,data){
    3     if(err){
    4         console.log("read file err");
    5     }else{
    6         console.log(data);
    7     }
    8 })
    9 console.log("end,");

    结果:end

         文件内容

    1.2、同步式读取文件

    1 var fs = require("fs");
    2 var data = fs.readFileSync("file.txt","UTF-8");
    3 console.log(data);
    4 console.log("end");

    结果:文件内容

        end

    1.3、分析

    调用时所做的工作只是将异步式IO请求发送给了操作系统,然后立即返回并执行后面的语句,执行完以后进入事件循环监听事件,当fs接收到IO请求完成的事件时。事件循环会主动调用回调函数完成后续工作。同步则是阻塞等待文成后,继续执行

    2、事件

    2.1、普通事件的使用

    //声明事件对象
    var EventEmitter = require("events").EventEmitter;
    var event = new EventEmitter();
    //注册事件
    event.on("some_event",function(){
       console.log(111); 
    })
    //触发事件
    setTimeout(function(){
       event.emit("some_event"); 
    },3000)

    2.2、node.js的事件循环机制

    node.js在什么时候进入事件循环呢

    node.js程序是由事件循环开始,到事件循环结束,所有的逻辑都是事件的回调函数

    如何使用自定义事件呢?

    事件的回调函数在执行过程中,可能会发出IO请求或直接发射(emit)事件,执行完毕后再返回事件循环

    五、模块和包

    概念:模块和包是node.js最重要的支柱。开发一个具有一定规模的程序不肯只用一个文件,通常需要把各个功能拆分、分装、然后组合起来。模块正是为了实现这种方式而诞生,在浏览器JavaScript中,脚本模块的拆分和组合通常使用html的script标签来实现,node.js提供了require函数来调用其他模块,而且模块都是基于文件,模块和包的区别是透明的,经常不做区分

    1、模块

    1.1、什么是模块

    模块和文件是一一对应的。一个node.js文件就是一个模块,这个文件可能是JavaScript代码、json或者编译过的c/c++扩展。

    var http = require("http"),其中http是node.js的一个核心模块,通过require函数获取这个模块,然后使用其中的对象

    1.2、创建及加载模块

    (1)创建模块

    node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即获取模块的exports对象

    module.js

    1 var name;
    2 exports.setName = function(theName){
    3     name = theName;
    4 }
    5 exports.sayHello = function(){
    6     console.log("hello"+name);
    7 }

    getModule.js

    1 var myModule = require("./module");
    2 myModule.setName("wang er");
    3 myModule.sayHello();

    (2)单次加载

    上面的例子类似创建一个对象,但实际上和对象又有本质的区别,因为require不会重复加载模块,无论调用多少次require,获取的模块都是同一个

    getModule2.js

    1 var myModule1 = require("./module");
    2 myModule1.setName("wang wu");
    3 var myModule2 = require("./module");
    4 myModule2.setName("hello world");
    5 myModule1.sayHello();

    (3)覆盖exports

    有时我们想把一个对象封装到模块中

    定义模块:singleobject.js

     1 function hello(){
     2     var name;
     3     this.setName = function(theName){
     4         name = theName;
     5     }
     6     this.sayHello = function(){
     7         console.log("hello"+name);
     8     }
     9 };
    10 module.exports = hello;

    引入模块使用:getsingleobject.js

    1 var hello = require("./singleobject");
    2 var he = new hello();
    3 he.setName("sugar");
    4 he.sayHello();
    5 var he2 = new hello();
    6 he2.setName("txy");
    7 he2.sayHello();

    exports本身仅仅是一个普通的空对象,即{},它是专门用来声明接口

    2、创建包

    2.1、包的概念

    包是在模块基础上更深一步的抽象,node.js的包类似于c/c++的函数库或者Java的类库,它将某个独立的功能封装起来,用于发布、更新、依赖管理的版本控制。开发了npm来解决包的发布和获取需求。

    2.2、如何创建一个包

    commonJS规范的包具备以下特征:

      package.json必须在包的顶层目录下

      二进制文件应该在bin目录下

      JavaScript代码应该在lib目录下

      文档应该在doc目录下

      单元测试应该在test目录下

    Node.js对包要求没有那么严格,只要顶层目录下有package.json,并符合基本规范即可

    (1)作为文件夹的模块

    somepackage文件夹(最简单的包,就是作为文件夹的模块)

    创建一个文件夹somepackage,里面有一个index.js,里面提供一个方法sayHello()

    var somepackage = require("./somepackage");

    somepackage.sayHello();

    使用这种方法可以把文件夹封装成一个模块,即包。包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库,通过定制package.json,我们可以创建更符合规范的包进行发布。

    (2)package.json

    在somepackage文件夹下,我们创建一个package.json的文件,内容{"main":"./lib/index.js"}

    node.js在调用某个包时,会检查包中package.json文件的main字段,将其作为包的接口模块,如果package.json或main字段不存在,会寻找index.js或index.code作为包的接口

    package.json的规范属性:

    name:包的名称,必须是唯一

    description:包的简要说明

    version:符合语义化版本识别规范的版本字符串

    keywords:关键字数据,通常用于搜索

    maintainers:维护者数组,每个元素要包含name、email、web可选字段

    contributes:贡献者数组,格式与maintainers相同。包的作者应该是贡献者数据的第一个元素

    bugs:提交bug的地址,可以是网址或者是电子邮件地址

    licenses:许可证数组,每个元素要包含type、url字段

    repositories:仓库托管地址数组,每个元素要包含type、url、和path、字段

    dependencies:包的依赖,一个关联数组,由包名称和版本号组成

  • 相关阅读:
    redis整合springboot
    安装k8s
    线程池工具类几种实现
    数据库mysql注意点及sql优化
    五年规划
    在 Ubuntu 16.04 安装ROS Kinetic 教程
    谈谈form-data请求格式 js
    C# Body为form-data file文件上传至第三方接口 http请求
    .net c# 使用form-data方式发起http请求
    使用form-data和raw作为body发起POST请求的区别
  • 原文地址:https://www.cnblogs.com/tianxinyu/p/5523363.html
Copyright © 2020-2023  润新知