热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

快速入门nodejs学习

nodejs学习简介nodejs是一个事件驱动IO服务端的JavaScript环境,没有DOM,浏览器之类的东西。Chrome的V8引擎是用C++写的,执行JS速度快。powers




nodejs学习


简介


  • nodejs是一个事件驱动I/O服务端的Javascript环境,没有DOM,浏览器之类的东西。
  • Chrome的V8引擎是用C++写的,执行JS速度快。
  • powershell是功能更强的cmd。

创建服务

创建一个http服务由以下3个部分构成:


  • 引入模块,require,把这个模块用一个变量接收。

    var xx = require(“http”);

  • 创建服务器

  • 处理请求与响应

    //创建一个服务
    //引入一个模块,把这个模块保存在 _httpv变量当中
    var _httpv = require("http");
    // console.log(_httpv.createServer)
    _httpv.createServer(function(request,response){
    //http头部的信息
    //状态码200
    //内容的类型:text/plain(纯文本), text/html(html形式)..., xml
    response.writeHead(200,{'Content-Type':'text/html'});
    //向客户端发送数据
    response.end("hello nodejs");
    }).listen(8080);
    //控制台打印信息
    console.log("8080已经创建!")


本质

创建各种服务,通过各种接口,提供各种数据。


基本概念


异步编程

异步编程的直接体现:异步回调的直接体现:异步回调

1.开发语言是js,js本身就是事件驱动的,是异步的;

2.因为是js的,所以是单线程的,现在是多线程的。

通过异步来处理大并发:

阻塞的例子:.readFileSync(文件名)是同步读取文件

// 通过异步来处理大并发(一个阻塞的例子)
//在nodejs中操作文件使用的是fs模块
var _fs = require("fs");
// console.log(_fs.readSync)
//.readFileSync是同步读取文件
var _data = _fs.readFileSync('New Collection.postman_collection.json');
//直接输出会是个二进制的流,此时可以采用toString方法
// console.log(_data);
console.log(_data.toString());
console.log('js已经执行结束');
/*
这种操作在本质上已经形成了阻塞
*/

非阻塞的例子:.readFile()基于回调的异步读取文件

//基于回调的非阻塞的文件读取
var _fs = require('fs');
//第一个参数是要读取的文件名
//第二个参数是处理读取到的文件的内容的回调函数
_fs.readFile('New Collection.postman_collection.json',function(err,_data)){
if(err) return err;
console.log(_data.toString());
};
console.log("----------");
console.log("js已经执行结束!");
/*
我们不需要等待文件读取完成,可以在读取文件的时候同时去执行下面的代码,提高了js的性能。
*/

回调的例子:回调的函数一般是作为最后一个形参出现。

实际工作中,最具体的应用就是jq的$.ajax()。




nodejs的事件(一)


  • nodejs是一个单进程单线程的应用程序,由于V8引擎提供了异步执行回调的接口,通过这些接口处理大的并发请求,性能很高。

  • 基本上nodejs所有的事件机制,都是基于设计模式中的“观察者模式”来实现的。

  • nodejs使用事件驱动的模型:每当接收到一个请求,就把它关掉进行处理,当这个请求完成,就把它放到处理队列当中,最后把结果返回给用户。

  • 由于nodejs的服务一直都是处理接收请求,但不等待任何的读写操作,所以性能很高,这也叫“非阻塞式的I/O或是事件驱动I/O"。

    nodejs的事件是使用 events 模块(require(“events”)),通过实例化( var event = new xx.EventEmitter)它里面的 EventEmitter 类来绑定和监听事件。

  • 绑定事件:event.on(…)

  • 监听事件:event.emit(…)

    node中的js,依然还是那个js,依然是从上到下一行一行的读取的解释型的脚本语言。编写时依然要注意顺序。

    /*
    nodejs 事件
    */
    var _events = require("events");
    //EventEmitter的一个实例
    var _EventEmitter = new _events.EventEmitter();
    //这里的事件名,完全不同于浏览器的各种事件,这里完全就只是一个标识,它其实是绑定了一个回调函数。
    _EventEmitter.on("xx123",function(){
    console.log("xx123事件已经被触发");
    //事件的嵌套
    _EventEmitter.emit("xx456");
    });
    _EventEmitter.on("xx456",xx456fn);
    function xx456fn(){
    console.log("xx456事件已经被触发");
    }
    //触发一个事件
    _EventEmitter.emit("xx123");
    console.log(_EventEmitter);


nodejs的事件(二)


  • nodejs里面所有异步的io操作,都会在完成时,发送一个事件到事件队列。
  • events这个模块只有一个对象events.EventEmitter,它的核心就是“事件触发与监听功能的封装”。

//第一个nodejs的事件的例子
var _EventEmitter = require("events").EventEmitter;
var _event = new _EventEmitter();
_event.on("timeout",function(){
console.log("timeout 事件被触发!");
})
setTimeout(function(){
_event.emit("timeout");
},2000)
console.log(_event);

  • EventEmitter,它的每个事件都是由:

    1.事件名,是一个字符串

    2.若干个参数

可以在一个实例上,通过on绑定多个事件,然后通过同一个.emit()方法触发并传参。如下实例:

//可以在一个实例上,通过on绑定多个事件,然后通过同一个.emit()方法触发并传参
var _EventEmitter = require("events").EventEmitter;
var _event = new _EventEmitter();
_event.on("xx1",function(arg1,arg2){
console.log("xx11111",arg1);
})
_event.on("xx1",function(arg1,arg2){
console.log("xx22222",arg2);
})
_event.emit("xx1","这是1111","这是2222");

Buffer(缓冲区/缓存)


  • nodejs的开发语言就是js,Javascript语言自身只有字符串数据类型,没有二进制数据类型。
  • nodejs有时会操作一些文件,或者说是tcp流之类的东西,那就必须操作二进制数据。
  • 在nodejs中,有一个buffer类,它用来创建一个专门存放二进制数据的缓存区。
  • buffer类是随nodejs的核心一起安装的,直接引入即可,这些原始数据是存储在buffer类的实例里,一个buffer类相当于是一个整数的数组,它相当于是划出了一块自己的内存空间。
  • buffer类的实例用于表示 编码字符 的序列,它支持utf-8,base64,ascii等。

1.创建一个Buffer类:

Buffer.alloc,它是返回一个指定大小的Buffer实例。

//创建一个长度为10,并且用0填充的buffer
const buf1 = Buffer.alloc(10);

2..write()向buffer实例中写入内容:

3..toString(),从缓冲区中读取数据。下面是其中的参数:


  • 默认编码是utf8
  • start,开始位置
  • end,结束位置

//创建一个长度为10,并且用0填充的bufferconst buf1 = Buffer.alloc(256);let text = buf1.write("我是秃头小框");console.log(buf1);console.log("写入的字节数:"+text);console.log(buf1.toString());console.log(buf1.toString('utf8',0,3));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mMGOonTk-1622692398527)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210527151818913.png)]

例子:

//批量输出26个字母const buf = Buffer.alloc(26);for(var i=0;i<26;i++){ buf[i] = 97 + i;}console.log(buf);console.log(buf.toString());console.log(buf.toString("ascii"));

4.将Buffer转换为JSON对象:


  • buf.toJSON(),它的返回值是一个json对象。

  • 调用Buffer.from(),它是返回一个被array的值,初始化之后的新的Buffer实例。

  • array之中的元素只能是数字,否则会被0覆盖。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);console.log(buf1);

5.JSON.stringify(),用于将Javascript值(对象/数组)转化为一个JSON字符串。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);const _json = JSON.stringify(buf1);console.log(buf1);console.log(_json);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gw8YWj7R-1622692398534)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210527154913845.png)]

6.JSON.parse()是将json字符串,转为json对象。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);const _json = JSON.stringify(buf1);console.log(buf1);console.log(typeof _json);//字符串类型console.log(typeof JSON.parse(_json));//对象类型console.log(typeof JSON.parse(_json).data);

Stream流


  • Stream流(简单理解就是一个在线读取的资源),是一个抽象的接口,在nodejs当中,很多方法、对象。它们都实现了这个接口。

    例如:之前创建一个服务,向服务器发起一个请求,request对象,它其实就是个Stream。

  • 在nodejs当中,Stream有四种流类型:


    • Readable —可读操作
    • Writeable —可写操作
    • Duple—可读可写操作
    • Transform —操作被写入数据,然后读出结果
  • 所有的Stream对象,都是EventEmitter的实例,常用的事件:


    • data 当有数据可读取时触发
    • end 没有更多的数据可读取时触发
    • error 在接收和写入过程中,发生错误时触发
    • finish 所有的数据读取完成时触发

虽然是从流中去读取文件,但是依然是在操作文件,所有还是要用到nodejs当中的fs模块。


读取流示例

var fs = require('fs');var data = '';//创建一个可读流var readStream = fs.createReadStream("Words.txt");//设置可读流的编码格式,utf8readStream.setEncoding('utf8');//处理流的事件,data,error,endreadStream.on('data',function(_d){ data += _d;});readStream.on('end',function(){ console.log(data);});console.log("读取完毕!");

写入流示例

var fs = require('fs');var data = '我是秃头小框,我喜欢这个世界!';//创建一个可以写入的流var writeStream = fs.createWriteStream("writedemo.txt");//设置编码writeStream.write(data,'utf8');//标记文件末尾writeStream.end();writeStream.on('finish',function(){ console.log("写入完成!");});console.log("执行完成了!");

  • nodejs中的管道流,提供了一个从输出流到输入流的机制(就像水龙头一样,从一个地方流入到了另一个地方),就是从一个流当中获取数据,并传递到另一个流当中,主要用到了,.pipe()方法。

管道流示例

var fs = require('fs');//创建一个可读流,createReadStreamvar readStream = fs.createReadStream("writedemo.txt");//创建一个可以写入的流var writeStream = fs.createWriteStream("pipedemo.txt");//管道流操作readStream.pipe(writeStream);console.log("执行完毕!");

  • 链式流就是从一个输出流中读取数据,创建了多个流来操作这个输出流的数据的机制。一般用来操作管道流,常见的例子就是压缩和解压缩(zlib)。

链式流示例

压缩:

var fs = require('fs');var zlib = require('zlib');//压缩文件fs.createReadStream("writedemo.txt") .pipe(zlib.createGzip()) .pipe(fs.createWriteStream("writedemo.txt.gz"));console.log("压缩完了!");

解压缩:

var fs = require('fs');var zlib = require('zlib');//解压缩文件fs.createReadStream("writedemo.txt.gz") .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream("Gunzipwritedemo.txt"));console.log("解压缩完了!");

模块系统


  • 模块是nodejs应用程序的基本组成部分。

  • 文件和模块是一一对应的,一个是nodejs的文件,就是一个模块。

  • nodejs提供了两个对象:


    • exports—它是模块公开的接口
    • require—用来获取外部的模块的接口
  • 创建模块的两种方式


    • 只公开一个方法(一般公开的方法名和它所在的模块是同名的):exports.方法名 = function(){ … }
    • 把整个模块都全部公开出来:moudle.exports = function(){ … }

get请求


  • 获得get请求的内容,它的内容是在URL的?号之后的部分(例如:?a=1&b=2&c=3):


    • util(nodejs的工具对象,有许多许多的方法)
    • util.inspect,用来把对象转换为字符串
    • url,是nodejs的url模块
    • url.parse,解析url请求之类的东西

    js//get请求var _http = require('http');var _util = require('util');var _url = require('url');_http.createServer(function(req,res){ res.writeHead(200,{ 'Content-Type':'text/plain;charset=utf-8' }); var _param = _url.parse(req.url,true).query; console.log(_param); // res.end('xx123'); //end方法只能向页面发送字符串 //res.end(_url.parse(req._url));error:_url.parse(req._url)是一个对象 // res.end(_util.inspect(_url.parse(req._url))); res.write("姓名:"+_param.name); res.write("\n"); res.write("年龄:"+_param.age); res.end();}).listen(5642);console.log('5642端口服务已经打开');


post请求


  • 要用到querystring,用来解析url的,querystring.parse(),用于将一个字符串转换为对象。

    //post请求var _http = require('http');var querystring = require('querystring');var _formHtml = '' + '姓名:
    '+ '年龄:
    '+ '' + '';_http.createServer(function(req,res){ var body = ''; req.on('data',function(_d){ body += _d; }); req.on('end',function(){ body = querystring.parse(body); res.writeHead(200,{ 'Content-Type':'text/html;charset=utf-8' }); if(body.name){ res.write('姓名:' + body.name); res.write('
    '); res.write('年龄:' + body.age); } else{ res.write(_formHtml); } res.end(); });}).listen(5642);console.log('5642端口服务已经打开');


express框架


  • 一个简洁的nodejs web应用框架,它提供一些功能,可以帮助你快速地搭建一个完整的网站。
  • 核心特性:
    • 可以使用中间件来响应http请求
    • 可以设置一些简单的路由:(手动)
  • 安装 Express,npm install express --save(–save意思是安装在你的开发目录,而不是全局安装。)

使用express创建一个服务

var express = require('express');// console.log(express);var app = express();//'/',就是根路径app.get('/',function(req,res){ res.send('第一个express例子,创建一个服务');});app.listen(5472,function(){ console.log("5472已经启动");});

express路由


  • 简单的路由,就是一个最简单的spa单页应用

express创建路由

var express = require('express');// console.log(express);var app = express();//'/',就是根路径app.get('/',function(req,res){ res.send('1
a页面
b页面');});app.get('/a',function(req,res){ res.send('2
a1页面');});app.get('/a/a1',function(req,res){ res.send('2.1
回到首页');});app.get('/b',function(req,res){ res.send('1.1
b1页面');});app.get('/b/b1',function(req,res){ res.send('1.2回到首页');});app.listen(5472,function(){ console.log("5472已经启动");});

静态目录


  • Express有内置的中间件的设置,可以用来设置静态目录,express.static(),可以让我们通过http的方式,来访问静态文件。
  • 它的效果和我们把文件放在phpstudy服务器上面的效果是一样的。

var express = require('express');var app = express();//设置静态目录app.use(express.static('staticDev'));app.listen(5472,function(){ console.log('5472,静态目录,已经启动');});


推荐阅读
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
author-avatar
Smile--麦芽
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有