Node.js简单理解 入门使用(前端方向)

目录

Node.js是什么?

Node.js特性

 npm

require详解

API使用:  fs     http      path

express框架

Node.js是什么?

  • 不是一门语言,不是,不是框架
  • 是一个JavaScript运行时环境,简单点说就是node.js可以解析和执行JavaScript代码
  • nodejs使用JavaScript语言编程,运行在JavaScript引擎上(V8
  • node.js为JavaScript提供了许多服务器级别的操作API(http,fs等)
  • node.js包含EcmaScript,但是不包含DOM,BOM,编码方法同JavaScript
  • node.js是一个基于 Chrome浏览器 V8 引擎的 JavaScript 运行时(环境)
  • node可以理解为是nodejs的作者基于Chrome浏览器的V8引擎,使用JavaScript开发的一个平台(环境),所以node可以解析和执行JavaScript代码

Node.js特性

  • 单线程
    在Java,PHP或者.net语言中,会为每一个客户端连接创建一个新的线程,而每个线程需要耗费大约2MB内存,所以就会 限制同时连接的用户数量。Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程,当有用户连接了就触发一 个内部事件,通过非阻塞I/O、事件驱动机制,让Nodejs程序宏观上也是并行的,大大提高用户的连接数量(性能)。
  • 非阻塞IO模型(IO指 input  output  输入 输出)
    当在访问数据库取得数据的时候,需要一段时间,在传统的单线程处理机制中,在执行了访问数据库代码之后,整个线程都  将暂停下来,等待数据库返回结果,才能执行后面的代码,也就是说,I / O阻塞了代码的执行,极大的降低了程序的执行效率,而Nodejs中采用了非阻塞型I / O机制,因此在执行访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回的结果处理代码放在回调函数中,从而提高了程序的执行效率,当某个I / O执行完毕时,将以事件的形式通知执行I / O操作的线程,线程执行这个事件的回调函数,为了处理异步I / O,线程必须有事件循环,不断的检查有没有未处理的 事件,依次予以处理。阻塞模式下,一个线程只能处理一项任务,想要提高吞吐量必须通过多线程,而非阻塞模式下,一个线程永远在执行计算操作,这个线程的CPU核心利用率永远是100 %。
  • 事件驱动
    在Nodejs中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在Node中,在一个时刻,只能执行一个事件回    调函数,但是在执行一个事件回调函数的中途,可以转而处理其他事件(比如,又有新用户连接了),然后返回继续执行      原  事件的回调函数,这种处理机制,称为“事件环”机制。

  • 轻量和高效 

  • 没有全局作用域
    只有模块作用域,所以不能进行像JavaScript那样的变量等的访问、调用操作
  • Nodejs中没有根目录(目录)的概念,因为它没有任何的web容器(可以理解成相当于一个服务器,如Apache/Tomcat)

 npm

  • 是一个基于node.js开发的包管理工具
  • npm是世界上最大的开源库生态系统
  • 绝大多数JavaScript相关的包都存放在了npm上,用以方便开发人员的下载及使用 

 使用Node.js,首先应该下载安装,推荐node.js官方网站下载,下载后直接安装(选择下一步即可)。

require详解

nodejsrequire使用非常频繁,或者说在模块化开发中起到非常重要的作用,使用通常类似这样:

var fs = require('fs')
const http = require('http')

 可是你真的了解它吗?在node中require方法有两个作用

  1. 加载文件模块并执行里面的代码
  2. 拿到被加载文件模块导出的接口对象  (exports)

 假设,当前有两个文件,a.jsb.js,文件中分别导入或导出了一些变量、方法等,如下:

// a.js
var app = 'algjalsgjals'
var fun = function () {
  return '777777777777'
}
// exports.app = app
// exports.fun = fun
// b.js
var adata = require('./a.js')
console.log(adata)

// console.log(exports) // 不会报错,输出值为 { }

 当注释a模块中的最后两行代码,运行b模块,输出的adata为一个空对象 { }

而取消对exports的注释,运行b模块,输出的adata为:{ app: 'algjalsgjals', fun: [Function: fun] }

那么,这说明什么问题呢:

  • 在node中每个文件模块默认都提供了一个exports对象,exports默认是一个空对象
  • 而你所要做的就是把需要被外部访问到的成员挂载到 exports 对象上(这也就是exports的作用)
  • 当a模块中的变量等没有挂载到 exports 对象上时,在b模块中是无法访问到的
  • 所以 require 的主要作用: 1 加载执行代码  2 拿到被加载模块导出的接口对象 (exports)

对模块化及require、import等不太熟悉的,推荐一篇博文,探索 模块打包 exports和require 与 export和import 的用法和区别 

              API使用

Nodejs中提供了很多的API功能,前端实际开发中用的不多,本文重点在于理解node的原理及日常使用,了解前端开发中常用的node功能模块,其他很多的功能模块,这里不一一详解,举几个简单的例子,具体使用详解参见Nodejs中文文档。 

 fs

FileSystem,文件系统,样例:

// 引入fs模块
const fs = require('fs')
// 读文件
fs.readFile('./我的生词本.txt', function (err, data) {
  console.log(data.toString())
  console.log(err)
})
// 写文件
fs.writeFile('./writeFile.txt', '大家好,我是帅哥!', function (err) {
  console.log('文件写入成功')
  console.log(err)
})

http 

使用http  API可以快速的创建一个服务器

// 引入http模块
const http = require('http')
// 创建一个web服务器(使用createServe方法,返回一个Serve实例)
var serve = http.createServer();
// 注册 request 请求事件(当客户端发请求过来就会自动触发 request 请求事件,执行回调函数)
// 回调函数接收两个参数,request,response
// request是客户端发送的请求信息
// response有一个write方法,可以用来向客户端发送响应信息
serve.on('request', function (request, response) {
  console.log('客户端请求发送成功')
  // console.log(request)
  response.writeHead(200, { 'Content-Type': 'text/plain;charset=UTF8' })// 设置响应头
  response.write('这是服务端向客户端响应的内容~~~')
  response.write('nodejs')
  // 通过response.end方法结束响应,告诉客户端,服务端响应完毕
  response.end()
})
// 绑定端口号,启动服务器
serve.listen('5000', function () {
  console.log('服务器启动成功了~')
})
// 创建一个服务,并加载html文件,展示页面
var http=require("http");
var fs=require("fs"); //导入文件模块
var server =http.createServer(function(req,res){
    //设置头信息
    res.setHeader("Content-Type","text/html;charset='utf-8'");
    //读文件
     fs.readFile("./index.html","utf-8",function(err,data){
         if(err) {
           console.log("index.html loading is failed :"+err);
         } else {
           //返回index.html页面
           res.end(data);
         }
     });
}).listen(8888); //监听端口,注:一个程序只能监听一个端口

path

path模块提供了一些用于处理文件与目录的路径的实用工具。

最常用的resolve方法:

// path
const path = require('path')
// 使用如:
index: path.resolve(__dirname, '../dist/index.html'),
// path.resolve() 方法将路径或路径片段的序列解析为绝对路径,
// 给定的路径序列从右到左进行处理,每个后续的 path 前置,直到构造出一个绝对路径
// 如果任何参数不是字符串,则抛出 TypeError

Node.js中提供了两个与文件操作相关全局可用变量__dirname__filename,__dirname表示当前文件所在的目录,__filename表示正在执行脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。如果在模块中,返回的是模块文件所在的路径。

// 举例说明
// path.resolve([…paths])里的每个参数都类似在当前目录执行一个cd操作,从左到右执行,返回的是最后的当前目录
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'
// 相当于cd /foo/bar //此时路径为 /foo/bar   cd /tmp/file/ //此时路径为 /tmp/file

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果当前工作目录为 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'

express框架

express是基于 Node.js 平台,快速、开放、极简的 Web 开发框架。

原生的node开发存在很多问题:

  • 呈递静态页面很不方便,需要处理每个http请求,还要处理304问题
  • 路由处理代码不直观清晰,需要很多正则表达式和字符串函数
  • 不能集中精力写业务,要考虑很多其他的东西

所以express框架应运而生: 

  • express框架有着惊艳的路由能力,正则提取数据能力足够一般工作使用
  • express中的静态文件处理就是一句话的事
  • express与模板引擎的配合更直观清晰
// Express安装
npm install express --save
// 使用案例
var express = require('express')
var app = express()

// Nodejs跨域问题解决及基本数据类型配置
app.all('*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*")
  res.header("Access-Control-Allow-Headers", "X-Requested-With")
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")
  res.header("X-Powered-By", "3.2.1")
  res.header("Content-Type", "application/json;charset=utf-8")
})

app.get('/haha', function (req, res) {
  res.send('这里是哈哈的页面')
})
app.get(/^\/student\/([\d]{10})$/, function (req, res) {
  res.send('学生信息,学号:' + req.params[0])
})
app.listen(3000, function() {
    console.log("服务器启动成功了~")
})

 

你可能感兴趣的:(nodejs,nodejs,http,fs,js)