NodeJS的优缺点入门笔记,大神请绕路!!!
简单的说 Node.js 就是运行在服务端的 Javascript。
Node.js 是一个基于Chrome Javascript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端Javascript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
- 优点:
1.高并发(高并发的时候,会出现数据库连接数不够用的情况,网上还有对应解决方案,还未实践)
2.适合I/O密集型应用
3.事件驱动、非阻塞I/O、高效、轻量
解决数据库高并发,程序解决方案:
数据库高并发时,连接数不够。平台监听sql *** 作,如果状态是ready,就回调执行sql *** 作。相当于将sql *** 作也做异步回调处理,每次sql *** 作都是在上次 *** 作ready后,再执行,强制串行执行sql *** 作。这样就减轻数据库压力。但是也可能导致整个应用变慢。
var proxy = new EventProxy(); var status = "ready"; var select = function(callback){ proxy.once("selected",callback); if(status == "ready"){ status = "pending"; db.select("SQL", function(results){ proxy.emit("selected",results); status = "ready"; }); }
- 缺点:
1.不适合CPU密集型应用;
CPU密集型应用给Node带来的挑战主要是:由于Javascript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;
解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;
2.只支持单核CPU,不能充分利用CPU(可以利用多进程利用cpu的,cluster就可以让你做到nodejs将电脑多核利用起来)解决方案:
(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
(2)开多个进程监听同一个端口,使用cluster模块;
1. RESTful API
这是NodeJS最理想的应用场景,可以处理数万条连接,本身没有太多的逻辑,只需要请求API,组织数据进行返回即可。它本质上只是从某个数据库中查找 一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的API需求。
2. 统一Web应用的UI层
目前MVC的架构,在某种意义上来说,Web开发有两个UI层,一个是在浏览器里面我们最终看到的,另一个在server端,负责生成和拼接页面。
不讨论这种架构是好是坏,但是有另外一种实践,面向服务的架构,更好的做前后端的依赖分离。如果所有的关键业务逻辑都封装成REST调用,就意味着在上层 只需要考虑如何用这些REST接口构建具体的应用。那些后端程序员们根本不 *** 心具体数据是如何从一个页面传递到另一个页面的,他们也不用管用户数据更新是 通过Ajax异步获取的还是通过刷新页面。
3. 大量Ajax请求的应用
例如个性化应用,每个用户看到的页面都不一样,缓存失效,需要在页面加载的时候发起Ajax请求,NodeJS能响应大量的并发请求。总而言之,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景。
演示一:Hello World!脚本模式
以下是我们的第一个Nodejs程序:
console.log("Hello World");
保存该文件,文件名为 helloworld.js, 并通过 node命令来执行:node helloworld.js。程序执行后,正常的话,就会在终端输出 Hello World。
image.png交互模式
打开终端,键入node进入命令交互模式,可以输入一条代码语句后立即执行并显示结果,例如:
$ node > console.log('Hello World!'); Hello World!image 演示二:nodejs基于http插件,监听接口,返回数据
1、新建app.js文件,然后并执行执行node app.js。
代码如下:
var http = require('http'); var server = http.createServer(function (req, res) { var body = ''; req.on('data', function(data) { // 接收客户端发送过来的数据, 也就是 xmlHttp.send(value); body += data; }); req.on('end', function() { res.writeHeader(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*' //解决跨域问题 }); res.write("hello:" + body); res.end(); }) }); server.listen(3000, function () { console.log('server start at localhost:3000'); });
2、找个引入jquery的页面,执行post请求:
$.ajax({ url:"http://localhost:3000", data:"我是快递小哥,请开开门", type:"post", success:function(d){console.log("success",d)}, error:function(d){console.log("error",d)} })
执行请求,返回hello:我是快递小哥,请开开门
image.png演示三:nodejs基于express插件,监听接口,返回数据这个例子中,nodejs充当后台,app.js中实现了http://loadlhost:3000接口,返回了前端提交的内容。
1、新建service.js文件,然后执行执行node service.js。
代码如下:
//demo const express = require('express'); const app = express(); //设置允许跨域访问该服务. app.all('*', function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); //Access-Control-Allow-Headers ,可根据浏览器的F12查看,把对应的粘贴在这里就行 res.header('Access-Control-Allow-Headers', 'Content-Type'); res.header('Access-Control-Allow-Methods', '*'); res.header('Content-Type', 'application/json;charset=utf-8'); next(); }); app.post('/hello', function (req, res) { res.json({title:"你好"}); }); const server = app.listen(8082, function () { console.log('Express app server listening on port %d', server.address().port); });
2、找个引入jquery的页面,执行post请求:
$.ajax({ url:"http://localhost:8082/hello", type:"post", success:function(d){console.log("success",d)}, error:function(d){console.log("error",d)} })
返回数据:
image.png 演示四:nodejs+express+mysql搭建后端环境引用:http://www.cnblogs.com/ssqqhh/p/6289690.html1、创建数据库
创建名为nodejs的数据库,新建一张users表,采用utf8编码。表结构和数据如下:
npm i express -g//安装express npm i express-generator -g//安装命令行工具 express --version//检测express是否安装成功
3、创建express项目
执行express express-demo,新建express项目,文件目录说明:
app.js//启动文件,或者说入口文件。新的页面以及页面相应的路由需要在这里配置; package.json//存储着工程的信息及模块依赖,当在 dependencies 中添加依赖的模块时,运行 npm install,npm //会检查当前目录下的 package.json,并自动安装所有指定的模块 node_modules//存放 package.json 中安装的模块,当你在 package.json 添加依赖的模块并安装后,存放在这个文件夹下 public//存放 image、css、js 等文件 routes//存放路由文件 views//存放视图文件或者说模版文件 bin//存放可执行文件
4、运行express项目
cd express-demo//进入项目 npm i//安装依赖文件 npm start//启动项目
启动成功,空荡荡的页面中就出现下面内容
image.png 5、写项目代码需要创建以下文件: modelconfig.js:数据库配置
module.exports = { mysql: { host: 'localhost', user: 'root', password: '123123', database: 'nodejs', port: 3306 } };
viewslogin.jade:登录页面
doctype html html head title link(href='/stylesheets/style.css', rel='stylesheet') link(href='/bootstrap-3.3.7/css/bootstrap.min.css', rel='stylesheet') script(src='/javascripts/jquery.min.js') script(src='/bootstrap-3.3.7/js/bootstrap.min.js') body(style='background: #dcd9da') // h1= title .container .row .col-md-4.col-md-offset-4 .panel.panel-default(style='margin-top: 100px') .panel-heading(style='background: #0d6aad') h4(align='center', style='color: #ffffff;') | express-jade-bootstrap-mysql-demo .panel-body(style='background: #e0e1ea') .form-group .input-group span.input-group-addon 账号 input#username.form-control(type='text', placeholder='请输入账号') .form-group .input-group span.input-group-addon 密码 input#password.form-control(type='password', placeholder='请输入密码') .form-group .col-lg-offset-7 | 没有账号? a(href='/register') 注册 .form-group button#login.btn.btn-success.btn-block(type='button') | 登录 #popup.alert.alert-warning a#close.close(href='#') × div(align='center') strong#popup-content(style='color: #b12e30;') script(type='text/javascript'). $(document).ready(function () { var username = $("#username"); var password = $("#password"); var login = $("#login"); var popup = $("#popup"); var popupContent = $("#popup-content"); var close = $("#close"); popup.hide(); close.click(function () { popup.hide(); }); login.click(function () { if (username.val() == "" || password.val() == "") { popup.show(); popupContent.html("账号或密码不能为空!"); } else { $.ajax({ url: "/login/userLogin", data: { username: $("#username").val(), password: $("#password").val() }, type: "POST", timeout: 36000, dataType: "text", success: function (data, textStatus) { //alert(data); var dataJson = eval("(" + data + ")"); if (dataJson.code == 200) { alert("登录成功"); window.location.href = "/"; } else if (dataJson.code == 300) { popup.show(); popupContent.html("账号不存在,请重新输入!"); } else if (dataJson.code == 400) { popup.show(); popupContent.html("密码有误,请重新输入!"); } else { popup.show(); popupContent.html("登录出错!"); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("error:" + textStatus); } } ); } }) ; }) ;
routeslogin.js:登录接口逻辑
var express = require('express'); var router = express.Router(); // 实现与MySQL交互 var mysql = require('mysql'); var config = require('../model/config'); // 使用连接池,提升性能 var pool = mysql.createPool(config.mysql); router.get('/', function (req, res, next) { res.render('login', { title: 'login' }); }); router.post('/userLogin', function (req, res, next) { var username = req.body.username;//获取前台请求的参数 var password = req.body.password; pool.getConnection(function (err, connection) { //先判断该账号是否存在 var $sql = "select * from users where username=?"; connection.query($sql, [username], function (err, result) { var resultJson = result; console.log(resultJson.length); if (resultJson.length === 0) { result = { code: 300, msg: '该账号不存在' }; res.json(result); connection.release(); } else { //账号存在,可以登录,进行密码判断 var $sql1 = "select password from users where username=?"; connection.query($sql1, [username], function (err, result) { var temp = result[0].password; //取得数据库查询字段值 console.log(temp); if (temp == password) { result = { code: 200, msg: '密码正确' }; } else { result = { code: 400, msg: '密码错误' }; } res.json(result); // 以json形式,把 *** 作结果返回给前台页面 connection.release();// 释放连接 }); } }); }); }); module.exports = router;
viewsregister.jade:注册页面
doctype html html head title link(href='/bootstrap-3.3.7/css/bootstrap.min.css', rel='stylesheet') script(src='/javascripts/jquery.min.js') script(src='/bootstrap-3.3.7/js/bootstrap.min.js') body(style='background: #dcd9da') nav.collapse.navbar-collapse.navbar-inverse .navbar-header a.navbar-brand express-jade-bootstrap-mysql-demo ul.nav.navbar-nav.navbar-right li(style='margin-right: 20px') a(href='/login') span.glyphicon.glyphicon-log-in | 登录 .container .row .col-md-4.col-md-offset-4 .panel.panel-default(style='margin-top: 40px') .panel-heading(style='background: #0d6aad') h3(align='center', style='color: #ffffff;') | 账号注册 .panel-body(style='background: #e0e1ea') .form-group .input-group span.input-group-addon 账 号 input#username.form-control(type='text', placeholder='请输入账号') .form-group .input-group span.input-group-addon 密 码 input#password.form-control(type='password', placeholder='请输入密码') .form-group .input-group span.input-group-addon 确认密码 input#password1.form-control(type='password', placeholder='请再次输入密码') .form-group .input-group span.input-group-addon 姓 名 input#name.form-control(type='text', placeholder='请输入姓名') .form-group button#register.btn.btn-success.btn-block(type='button') | 注册 #popup.alert.alert-warning a#close.close(href='#') × div(align='center') strong#popup-content(style='color: #b12e30;') script(type='text/javascript'). $(document).ready(function () { var username = $("#username"); var password = $("#password"); var password1 = $("#password1"); var name = $("#name"); var register = $("#register"); var popup = $("#popup"); var popupContent = $("#popup-content"); var close = $("#close"); popup.hide(); close.click(function () { popup.hide(); }); register.click(function () { if (username.val() == "" || password.val() == "" || password1.val() == "" || name.val() == "") { popup.show(); popupContent.html("注册信息不能为空!"); } else if (password.val() !== password1.val()) { popup.show(); popupContent.html("两次输入的密码不一样!"); } else { //访问服务器,将注册信息写入数据库 $.ajax({ url: "/register/userRegister", data: { username: $("#username").val(), password: $("#password").val(), name: $("#name").val() }, type: "POST", timeout: 36000, dataType: "text", success: function (data, textStatus) { var dataJson = eval("(" + data + ")"); if (dataJson.code == 200) { alert("注册成功"); window.location.href = "/login"; } else if (dataJson.code == 300) { popup.show(); popupContent.html("该账号已存在!"); } else if (dataJson.code == 400) { popup.show(); popupContent.html("注册失败,请重新注册!"); } else { popup.show(); popupContent.html("注册出错!"); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("error:" + textStatus); } }); } }); });
routesregister.js:注册接口逻辑
var express = require('express'); var router = express.Router(); // 实现与MySQL交互 var mysql = require('mysql'); var config = require('../model/config'); // 使用连接池,提升性能 var pool = mysql.createPool(config.mysql); router.get('/', function (req, res, next) { res.render('register', { title: 'register' }); }); router.post('/userRegister', function (req, res, next) { var username = req.body.username; var password = req.body.password; var name = req.body.name; //获取前台请求的参数 pool.getConnection(function (err, connection) { //先判断该账号是否存在 var $sql = "select * from users where username=?"; connection.query($sql, [username], function (err, result) { var resultJson = result; console.log(resultJson.length); if (resultJson.length !== 0) { result = { code: 300, msg: '该账号已存在' }; res.json(result); connection.release(); } else { //账号不存在,可以注册账号 // 建立连接,向表中插入值 数据库表名为user-info会出错 var $sql1 = "INSERT INTO users(id, username, password, name) VALUES(0,?,?,?)"; connection.query($sql1, [username, password, name], function (err, result) { console.log(result); if (result) { result = { code: 200, msg: '注册成功' }; } else { result = { code: 400, msg: '注册失败' }; } res.json(result); // 以json形式,把 *** 作结果返回给前台页面 connection.release();// 释放连接 }); } }); }); }); module.exports = router;
app.js:修改代码
... var login = require("./routes/login"); var register = require("./routes/register"); ... app.use('/login', login); app.use('/register', register); ...
jquery.min.js:引入jquery,放到public文件夹bootstrap:引入bootstrap,放到public文件夹
登陆成功 注册成功准备好以上代码后,执行npm start命令启动项目,打开登录页面:http://localhost:3000/login,注册页面:http://localhost:3000/register
参考: NodeJs+Express+SqlServer简易后台API服务搭建
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)