nodejs简单入门介绍part1

nodejs

nodejs是基于谷歌Chrome的V8引擎(JavaScript引擎)的服务端平台(或语言)。node于2009由
Ryan Dahl开发,可以轻松构建快速、可扩展的网络应用,它使用事件驱动、非阻塞IO模型让其变得
轻量和高效,可以完美跨平台支持数据实时交互的应用。

nodejs = 运行时环境 + JavaScript类库

特征

异步+事件驱动(Asynchronous and Event Driven)

node的所有API都是异步的(非阻塞,任何API不会等待数据返回)。node服务端通过事件通知机制,来
获得API的响应。

非常快(Very Fast)

基于谷歌Chrome的V8引擎,node类库可以快速执行代码。

单线程,但高扩展(Single Threaded but Highly Scalable)

node是基于单线程模型的,事件机制可以以非阻塞模式让node高扩展,而不是像传统应用创建有限的线程
去处理请求。node可以处理比传统服务器(Apache HTTP Server)更多量级的请求。

没有缓冲(No Buffering)

node不会缓冲任何数据,而是简单将数据放到chunk中。

适用&不适用场景

适用

I/O密集型应用
数据流型应用
数据实时交互型应用
JSON API类型应用
单页面型应用

不适用

CPU密集型应用

使用

$ cd /tmp
$ wget http://nodejs.org/dist/v6.3.1/node-v6.3.1-linux-x64.tar.gz
$ tar xvfz node-v6.3.1-linux-x64.tar.gz
$ mkdir -p /usr/local/nodejs
$ mv node-v6.3.1-linux-x64/* /usr/local/nodejs
node test.js

实例

概念

导入必须模块(Import required modules)
通过require指令导入node模块
创建服务(Create Server)
服务类似于Apache HTTP Server,是可以监听和影响客户端的请求的
请求&响应(Read request and return response)
接受请求,并做响应
// 引入模块
var http = require("http");

// 创建服务
http.createServer(function (request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});

    response.end('Hello node \n');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/')

包管理

npm, Node Package Manager

命令行

# 本地安装
npm install <Module Name>

# 全局安装
npm install <Module Name> -g

# 查看
npm ls -g

# 卸载
npm uninstall <Module Name>

# 搜索
npm search <Module Name>

package.json

定义依赖的包,类似maven的pom.xml

name: 包名称
version: 包版本
description: 包描述
homepage: 包首页
author: 包作者
contributors: 包贡献者
dependencies: 依赖列表(npm自动安装这些依赖)
repository: 包仓库地址
main: 包主要入口
keywords: 包关键字

创建包

npm init
npm adduser
npm publish

回调

回调类似一个异步函数,在任务完成时触发。node需要大量回调,所有API都支持回调。

// blocking
var fs = require("fs")

var data = fs.readFileSync('t.txt');

console.log(data.toString());
console.log("end");

// non-blocking
fs.readFile('t.txt', function(error, data){
    if (error){
        return console.log(error);
    }
    console.log(data.toString());
});
console.log("end");

事件

node虽然是单线程,但是可以通过事件和回调支持并发(观察者模式)。

事件驱动

函数类似观察者,当事件触发后,函数就会执行。

var events = require('events');

var eventEmitter = new events.EventEmitter();

var connectHandler = function connected(){
    console.log('connection successful');
    eventEmitter.emit('data_received');
}

eventEmitter.on('connection', connectHandler);

eventEmitter.on('data_received', function(){
    console.log('data received successful');
});

eventEmitter.emit('connection');

console.log('end');

EventEmitter

addListener(event,listener)
on(event,listner)
once(event,listner)
removeAllListeners([event])
setMaxListeners(n)
listeners(event)
emit(event, [arg1], [arg2], [..])

listenerCount(emmiter, event)

newListner(event, listener)
removeListener(event, listener)

例子

var events = require('events');
var eventEmitter = new events.EventEmitter();

// listener #1
var listner1 = function listner1() {
   console.log('listner1 executed.');
}

// listener #2
var listner2 = function listner2() {
   console.log('listner2 executed.');
}

// Bind the connection event with the listner1 function
eventEmitter.addListener('connection', listner1);

// Bind the connection event with the listner2 function
eventEmitter.on('connection', listner2);

var eventListeners = require('events').EventEmitter.listenerCount
   (eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");

// Fire the connection event 
eventEmitter.emit('connection');

// Remove the binding of listner1 function
eventEmitter.removeListener('connection', listner1);
console.log("Listner1 will not listen now.");

// Fire the connection event 
eventEmitter.emit('connection');

eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");

console.log("Program Ended.");

缓冲

node提供Buffer来存储原始数据(类似整型数组),buffer是一个全局类,可以不用import模块。

命令行

# 创建
var buf = new Buffer(10);
var buf = new Buffer([10, 20, 30, 40, 50]);
var buf = new Buffer("Simply Easy Learning", "utf-8");

# 写数据
buf.write(string[, offset][, length][, encoding])

string:字符串数据
offset:开始写入位置, 默认0
length:写入字节数量, 默认buffer.length
encoding: 编码,默认utf8

# 读数据
buf.toString([encoding][, start][, end])

encoding:编码,默认utf8
start: 开始读取位置,默认0
end:结束读取位置,默认读整个buffer

# 转json
buf.toJSON()

# 整合多个buffer
Buffer.concat(list[, totalLength])

# 比较buffer
buf.compare(otherBuffer);

# 复制buffer
buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])

# 截取buffer
buf.slice([start][, end])

Streams:从源头读取数据或写数据至目标。

# 类型
Readable: 读取
Writable: 写入
Duplex: 读写
Transform: 读写,输出是基于输入计算的

# 事件
data: 数据可读
end: 数据读取完毕
error: 读写出错
finish: 所有数据被刷新
var fs = require("fs");

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Pipe the read and write operations
// read input.txt and write data to output.txt
readerStream.pipe(writerStream);

console.log("Program Ended");

文件系统

var fs = require(“fs”);

var fs = require("fs");

// Asynchronous read
fs.readFile('input.txt', function (err, data) {
   if (err) {
      return console.error(err);
   }
   console.log("Asynchronous read: " + data.toString());
});

// Synchronous read
var data = fs.readFileSync('input.txt');
console.log("Synchronous read: " + data.toString());

console.log("Program Ended");

API

# 文件读写
fs.open(path, flags[, mode], callback)

path: 路径

flags: 
r(读,文件不存在抛异常)
r+(读写,文件不存在抛异常)
rs(同步读)
rs+(同步读写)
w(写,文件不存在创建,文件存在删除)
wx(同上,但文件不存在失败)
w+(读写,文件不存在创建,文件存在删除)
wx+(读写,文件不存在失败)
a(追加,文件不存在创建)
ax(追加,文件不存在失败)
a+(读&追加,文件不存在创建)
ax+(读&追加,文件不存在失败)

mode:权限,类似linux。默认0666(读写)
callback: 回调函数,两个参数(err,fd)

# 文件信息
fs.stat(path, callback)

callback: 回调函数,两个参数(err,stats)

stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink()
stats.isFIIO
stats.isSocket()

# 文件写
fs.writeFile(filename, data[, options], callback)

# 文件读
fs.read(fd, buffer, offset, length, position, callback)

# 关闭文件
fs.close(fd, callback)

# 删除文件
fs.ftruncate(fd, len, callback)

# 删除文件
fs.unlink(path, callback)

# 创建目录
fs.mkdir(path[, mode], callback)

# 读取目录
fs.readdir(path, callback)

# 删除目录
fs.rmdir(path, callback)

实例

# 文件读写
var fs = require("fs");

// Asynchronous - Opening File
console.log("Going to open file!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");     
});


# 文件信息
console.log("Going to get file info!");
fs.stat('input.txt', function (err, stats) {
   if (err) {
      return console.error(err);
   }
   console.log(stats);
   console.log("Got file info successfully!");
   
   // Check file type
   console.log("isFile ? " + stats.isFile());
   console.log("isDirectory ? " + stats.isDirectory());    
});

全局对象

node的全局对象,可以在所有模块可用。不需要在项目中引用,直接可使用。

__filename

文件全路径

__dirname

文件路径

setTimeout(cb, ms)

延迟执行

clearTimeout(t)

清除延迟

setInterval(cb, ms)

定时执行

Console

标准输出

Process

进程相关

常用模块

OS Module: 操作系统
Path Module: 文件路径
Net Module:网络
DNS Module: 域名解析
Domain Module: IO操作

web模块

web应用架构

Client:客户端
Server: 服务端
Business: 业务端
Data: 数据端

实例

# 服务端
var http = require('http');
var fs = require('fs');
var url = require('url');

// Create a server
http.createServer( function (request, response) {  
   // Parse the request containing file name
   var pathname = url.parse(request.url).pathname;
   
   // Print the name of the file for which request is made.
   console.log("Request for " + pathname + " received.");
   
   // Read the requested file content from file system
   fs.readFile(pathname.substr(1), function (err, data) {
      if (err) {
         console.log(err);
         
         // HTTP Status: 404 : NOT FOUND
         // Content Type: text/plain
         response.writeHead(404, {'Content-Type': 'text/html'});
      } else {	
         //Page found	  
         // HTTP Status: 200 : OK
         // Content Type: text/plain
         response.writeHead(200, {'Content-Type': 'text/html'});	
         
         // Write the content of the file to response body
         response.write(data.toString());		
      }
      
      // Send the response body 
      response.end();
   });   
}).listen(8081);

// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');

# 客户端
var http = require('http');

// Options to be used by request 
var options = {
   host: 'localhost',
   port: '8081',
   path: '/index.htm'  
};

// Callback function is used to deal with response
var callback = function(response) {
   // Continuously update stream with data
   var body = '';
   response.on('data', function(data) {
      body += data;
   });
   
   response.on('end', function() {
      // Data received completely.
      console.log(body);
   });
}
// Make a request to the server
var req = http.request(options, callback);
req.end();

Express框架

Express是一款常用的基于Node的web应用框架,内置了一些组件可以提高开发效率。

1. 允许设置中间件响应HTTP请求
2. 定义了基于HTTP的URL和Method的路由表(请求分发器)
3. 允许基于参数和模块动态渲染页面

安装

npm install express --save
npm install body-parser --save
npm install cookie-parser --save
npm install multer --save

body-parser: 处理请求和响应body,比如json、text、form data
cookie-parser: 处理cookie相关
multer: 文件上传,处理multipart/form-data

实例

var express = require('express');
var app = express();

app.get('/', function(req, res){
    console.log();
    res.send('Hello Express Get');
})

app.post('/', function(req, res){
    console.log('Got a POST request for the homepage');
    res.send('Hello Express Post');
})

// This responds a GET request for the /list_user page.
app.get('/list_user', function (req, res) {
   console.log("Got a GET request for /list_user");
   res.send('Page Listing');
})

// This responds a GET request for abcd, abxcd, ab123cd, and so on
app.get('/ab*cd', function(req, res) {
   console.log("Got a GET request for /ab*cd");
   res.send('Page Pattern Match');
})

// static resource
app.use(express.static('public'))
app.get('/index.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "index.htm" );
})

// get
app.get('/process_get', function (req, res) {
   // Prepare output in JSON format
   response = {
      first_name:req.query.first_name,
      last_name:req.query.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})


// Create application/x-www-form-urlencoded parser
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false })

// post
app.post('/process_post', urlencodedParser, function (req, res) {
   // Prepare output in JSON format
   response = {
      first_name:req.body.first_name,
      last_name:req.body.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})

// file
var fs = require("fs");
var multer  = require('multer');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}));

app.post('/file_upload', function (req, res) {
   console.log(req.files.file.name);
   console.log(req.files.file.path);
   console.log(req.files.file.type);
   var file = __dirname + "/" + req.files.file.name;

   fs.readFile( req.files.file.path, function (err, data) {
      fs.writeFile(file, data, function (err) {
         if( err ) {
            console.log( err );
            } else {
               response = {
                  message:'File uploaded successfully',
                  filename:req.files.file.name
               };
            }

         console.log( response );
         res.end( JSON.stringify( response ) );
      });
   });
})

// cookie
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.get('/', function(req, res) {
   console.log("Cookies: ", req.cookies)
})

var server = app.listen(8889, function(){
    var host = server.address().address
    var port = server.address().port

    console.log("app listening at http://%s:%s", host, port);
})

扩展

node虽然是单线程,但是也可以利用CPU多核能力,通过子线程来扩展能力

node提供了child_process模块专门处理子线程
命令:
child_process.exec(command[, options], callback): 运行命令
child_process.spawn(command[, args][, options]):开启子线程运行命令
child_process.fork(modulePath[, args][, options]):spawn的特殊场景,开启子线程运行命令

实例

const fs = require('fs');
const child_process = require('child_process');

// exec
for(var i=0; i<3; i++) {
   var workerProcess = child_process.exec('node support.js '+i,function
      (error, stdout, stderr) {

      if (error) {
         console.log(error.stack);
         console.log('Error code: '+error.code);
         console.log('Signal received: '+error.signal);
      }
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr);
   });

   workerProcess.on('exit', function (code) {
      console.log('Child process exited with exit code '+code);
   });
}

// spawn
for(var i = 0; i<3; i++) {
   var workerProcess = child_process.spawn('node', ['support.js', i]);

   workerProcess.stdout.on('data', function (data) {
      console.log('stdout: ' + data);
   });

   workerProcess.stderr.on('data', function (data) {
      console.log('stderr: ' + data);
   });

   workerProcess.on('close', function (code) {
      console.log('child process exited with code ' + code);
   });
}

// fork
for(var i=0; i<3; i++) {
   var worker_process = child_process.fork("support.js", [i]);	

   worker_process.on('close', function (code) {
      console.log('child process exited with code ' + code);
   });
}

JXcore打包

JXcore一个开源的,将源代码打包加密至JX包。

安装

# 下载
wget https://s3.amazonaws.com/nodejx/jx_rh64.zip

# 解压&安装
unzip jx_rh64.zip
cp jx_rh64/jx /usr/bin
export PATH=$PATH:/usr/bin
jx --version

命令

# 打包
jx package index.js index

# 运行&启动
node index.js command_line_arguments
jx index.jx command_line_arguments
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值