Node入门教程

根据Harry Han视频教程编写,Node入门教程

node windows平台版本管理工具nvm-windows

下载与安装

nvm-windows下载
安装前,这里有一点需要注意,如果以前安装过node,需要先卸载,并且要把目录清理干净。

nvm常用命令查看

nvm
image.png

查看当前已经安装的nodejs版本

nvm list
image.png

查看可以安装的nodejs版本

nvm list available
# https://nodejs.org/download/release
image.png

安装指定版本的node

nvm install 9.0.0 64-bit
# 安装最新版本
nvm install latest 64-bit

使用指定版本的node

nvm use 9.0.0
nvm list
image.png

删除指定版本的node

nvm uninstall 0.10.34

node命令

# 当前node版本号
node -v
# 直接执行一个eval语句
node -e "console.log(123)"
# 进入编译模式
node
image.png

创建一个服务器

# server.js
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

→ node server.js
image.png

点击图片中的链接就可以在默认浏览器中打开

证明node是单线程

一个线程阻塞,其他的就不能再访问了

# server.js
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  console.log(1)
  while(1){}
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});


→ node server.js
image.png

边写边改

npm install -g supervisor
supervisor server.js

回调函数

1.异步式读取文件

# file.js
let fs = require('fs');
fs.readFile('./file.txt', 'utf-8', (err, data) => {
  if (err) {
    console.log(err)
  } else {
    console.log(data)
  }
});
console.log('end.')

→ node file.js
image.png
  1. 同步式读取文件
# fileSyn.js
let fs=require('fs'); 
let data=fs.readFileSync('file.txt','utf-8');
console.log(data)
console.log('end.')

→ node fileSyn.js
image.png

事件

# event.js
//声明事件对象
let EventEmitter=require('events').EventEmitter;
let event=new EventEmitter();
//注册事件
event.on('some_event',function(){
    console.log('这是一个自定义的事件');
});
//触发事件
setTimeout(function(){
    event.emit('some_event');
},1000);

→ node event.js
image.png

模块

require不会重复加载模块

# moduleB.js
console.log('我被调用了!');
exports.add = (param1=0, param2=3) => {
    return param1 + param2;
}

# moduleB.js
let moduleA = require('./moduleA');
let moduleA2 = require('./moduleA');
console.log(moduleA.add());
console.log(moduleA2.add(3, 4));

→ node moduleB.js
image.png

注:重复引用时,后边的引用赋值会覆盖前面的

# person.js
let name;
exports.setName = thyName => {
    name = thyName;
}
exports.sayHello = () => {
    console.log('hello '+name);
}

# personMain.js
let person = require('./person');
let person2 = require('./person');

person.setName('LiLei');
person.sayHello();

person2.setName('HanMeimei');
person2.sayHello();
person.sayHello();

→ node personMain.js
image.png

不同方法暴露方法

[推荐] module.exports = 接口名称

# exportMethod.js
let sayHello = name => {
    console.log(name + ' ,你好!');
}

// exports.sayHello = sayHello;
module.exports = sayHello;

# exportMethodMain.js
// let sayHelloNode = require('./exportMethod');
// sayHelloNode.sayHello('小丽');

let sayHello = require('./exportMethod');
sayHello('小丽');

→ node exportMethodMain.js
image.png

process


描述当前Node.js进程状态的对象。提供了一个与操作系统的简单接口,通常写本地命令行程序的时候,会用到它
process.argv是命令行参数数组

  • 第一个元素是node
  • 第二个元素是脚本文件名
  • 第三个元素开始每个元素是一个运行参数
# argv.js
console.log(process.argv);

→ node argv.js "haha" "huhu" "piupiu"
image.png

process.nextTick(callback)方法

耗时的操作拆分为两个事件,减少每个事件的执行时间,提高事件响应速度

# nextick.js
const len = 1e9;

function fun1(param = '默认参数'){
    for(let i=0; i<len; i++){}
    console.log('传入的参数: ', param);
}

function fun2(){
    for(let i=0; i<len; i++){}
    console.log('计算方法2');
}

// function fun3(param, callback){
//  fun1(param);
//  callback();
// }

function fun3(param, callback){
    fun1(param);
    process.nextTick(callback);
}

fun3(123,fun2);

→ node nextick.js
image.png

util全局变量

1.util.inherits(constructor,superConstructor)
实现对象间原型继承的函数
注:只能继承原型链的方法,不能继承对象的方法

# demo.js
let util = require('util');

function Pather(){
    this.name = '老爸';
    this.age = 40;
    this.showName = function() {
        console.log('father name: ' + this.name);
    }
}
Pather.prototype.showAge = function() {
    console.log(this.name + ' ' + this.age);
}
function Child(){
    this.name = '儿子';
}
util.inherits(Child, Pather);
let child = new Child();
// child.showName();
child.showAge();

→ node demo.js
image.png

2.传统的原型链继承
注:原型链和对象的方法都可以继承

# demo.js
function Pather(){
    this.name = '老爸';
    this.age = 40;
    this.showName = function() {
        console.log('father name: ' + this.name);
    }
}
Pather.prototype.showAge = function() {
    console.log(this.name + ' ' + this.age);
}

function Child(){
    this.name = '儿子';
}
Child.prototype = new Pather();

let child = new Child();
child.showName();
child.showAge();

→ node demo.js
image.png

util.inspect(object,[showHidden],[depth],[colors])

此方法是一个将任意对象转换为字符串的方法,通常用于调试和错误输出,它至少接受一个参数object。
参数:

  • object,即要转换的对象.
  • showHidden 是一个可选参数,如果值为true,将会输出更多隐藏信息.
  • depth 标识最大的递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多少。默认为2层,指定为null打印出来全部
  • 如果color为true,输出格式将会以ANSI颜色编码,通常用于在终端显示更漂亮的效果。
# demo.js
let util=require('util');

function Person(){
    this.name='猫咪';
    this.toString=function(){
        return this.name;
    }
}
let obj=new Person();

console.log(util.inspect(obj));
console.log(util.inspect(obj,true,2,true));

→ node demo.js
image.png

事件

常用API的方法介绍:

  1. EventEmitter.on(event,listener)为指定事件注册一个监听器,接受一个字符串event和一个回调函数listener
  2. EventEmitter.emit(event,[arg1],[arg2]....) 发射event事件,传递若干可选参数到事件监听器的参数表
  3. EventEmitter.once(event,listener) 为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。
  4. EventEmitter.removeListener(event,listener)移除指定事件的某个监听器,listener必须是该事件已经注册过的监听器。
  5. EventEmitter.removeAllListeners([event]) 移除所有事件的所有监听器,如果指定event,则移除指定事件的所有监听器。
# demo.js
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('hungry', (food) => {
  console.log('饿了我给你做个' + food + '!');
});
myEmitter.once('hungry', () => {
  console.log('不用干活了,去看电视吧!');
});

myEmitter.emit('hungry', '鸡蛋');
myEmitter.emit('hungry', '鸡蛋');

→ node demo.js
image.png

error

error是特殊的事件
普通事件不捕获不会抛异常,error需要捕获

# demo.js
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('hungry', (food) => {
  console.log('饿了我给你做个' + food + '!');
});

myEmitter.emit('hungry', '鸡蛋');
myEmitter.emit('happy', '鸡蛋');
myEmitter.emit('error');


→ node demo.js
image.png

异常捕获的情况

# demo.js
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('error', () => {
  console.log('乖,妈妈抱抱!');
});

myEmitter.emit('error');


→ node demo.js
image.png

fs

文件系统

# demo.js
const fs = require('fs');

fs.readFile('content.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

let data = fs.readFileSync('content.txt', 'utf8');
console.log(data);

→ node demo.js
image.png

http服务器

# demo.js
const http = require('http');
const urls=require('url');
const util=require('util');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');

  let reqUrl = req.url;
  let urlParse = urls.parse(reqUrl,true);
  let utilInspect = util.inspect(urlParse)
  console.log(reqUrl)
  console.log(urlParse)
  console.log(utilInspect)

  res.end(utilInspect);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

→ node demo.js
http://127.0.0.1:3000/abc?param1=1&param2=2
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容