使用Node.js搭建一个简单的web服务器(一):Node.js入门
目录
什么是Node
- 一个允许我们在计算机/服务器上运行JavaScript的平台
- 可以读取,删除和更新文件
- 可轻松的与数据库通信
优势
- 使用JavaScript语言
- 非常快(在V8引擎上运行并使用非阻塞代码)
- 庞大的开源插件包生态系统 (npm)
- 适合实时服务(如聊天)
下载Node.js
https://nodejs.org/
(左侧为目前稳定版本,右侧为最新版本)
创建&引入模块(module)
基本使用
在count.js文件下编写需要用到的module,并在app.js引入并使用。
//count.js
const counter = (arr) => {
return `there are ${arr.length} elements in this array`;
};
module.exports = counter;
//必须export你想在其他文件使用的东西
//app.js
const counter = require('./count');
//counter==从count文件抛出的东西
console.log(counter(['shuan', 'cry', 'ryu']));
当一个文件中需要抛出多个东西
module文件的写法
写法一:
//stuff.js
const counter = function (arr) {
return `there are ${arr.length} elements in this array`;
};
const adder = function(a, b) {
return `the sum of the two numbers is ${a + b}`;
}
let pi = 3.142;
module.exports.counter = counter;
module.exports.adder = adder;
module.exports.pi = pi;
写法二:
//stuff.js
const counter = function (arr) {
return `there are ${arr.length} elements in this array`;
};
const adder = function(a, b) {
return `the sum of the two numbers is ${a + b}`;
}
let pi = 3.142;
module.exports = {
counter: counter,
adder: adder,
pi: pi
}
写法三:
//stuff.js
module.exports.counter = function (arr) {
return `there are ${arr.length} elements in this array`;
};
module.exports.adder = function (a, b) {
return `the sum of the two numbers is ${a + b}`;
}
module.exports.pi = 3.142;
app.js文件的写法
写法一:
//app.js
const {counter, adder, pi} = require('./stuff');
console.log(counter(['shuan', 'cry', 'ryu']));
console.log(adder(5, 6));
console.log(adder(pi, 5));
写法二:
const stuff = require('./stuff');
console.log(stuff.counter(['shuan', 'cry', 'ryu']));
console.log(stuff.adder(5, 6));
console.log(stuff.adder(stuff.pi, 5));
事件触发器
基本用法
//basic
const events = require('events');//导入Node的events模块
var myEmitter = new events.EventEmitter();//创建一个事件触发器对象
myEmitter.on('someEvent', (mssg) => {//注册监听器,给名为someEvent的事件的监听器数组末尾添加监听器(即该方法)
console.log(mssg);
});
myEmitter.emit('someEvent', 'the event was emitted');//触发someEvent事件的监听器,并传入参数
多个同类型的对象绑定事件触发器
方法一:
const events = require('events');
class Person extends events.EventEmitter {//让Person继承events.EventEmitter的特性
this.name = name;
}
const james = new Person('james');
const mary = new Person('mary');
const ryu = new Person('ryu');
const people = [james, mary, ryu];
people.forEach((person) => {//使用forEach为每个Person对象注册监听器
person.on('speak', (mssg) => {
console.log(`${person.name} said: ${mssg}`);
});
});
james.emit('speak', 'hey dudes');
ryu.emit('speak', 'i want a curry')
方法二:
const events = require('events');
const util = require('util');
const Person = (name) => {
this.name = name;
};
util.inherits(Person, events.EventEmitter);
// 使用util.inherits(constructor, superConstructor) 实现继承 constructor.super_=superConstructor
const james = new Person('james');
const mary = new Person('mary');
const ryu = new Person('ryu');
const people = [james, mary, ryu];
people.forEach((person) => {
person.on('speak', (mssg) => {
console.log(`${person.name} said: ${mssg}`);
});
});
james.emit('speak', 'hey dudes');
ryu.emit('speak', 'i want a curry');
两种继承方法语义上不兼容,建议使用第一种方法
读写文件
同步&异步
- 同步读写文件(Sync):文件读写完前不会执行下面的代码
- 异步读写文件:传入回调函数后继续执行后续代码
//read file
const fs = require('fs');
const readMe = fs.readFileSync('readMe.txt', 'utf8');//同步读取
fs.readFile('readMe.txt', 'utf8', (err, data) => {
fs.writeFile('writeMe.txt', data, (err) => {});
});//异步读取
console.log('test');
//test 会在fs.writeFile执行完之前打印
写文件
若同一文件目录下不存在‘writeMe.txt’,则创建新文件并写入数据,若存在则将文件内容替换成写入数据。写入数据必须为字符串或buffer二进制数据。
fs.writeFileSync('writeMe.txt', readMe);
fs.writeFile('writeMe.txt', data, (err) => {});
创建或删除目录
const fs = require('fs');
//删除文件
fs.unlink('writeMe.txt', (err) => {});
//创建 or 移除目录
fs.mkdirSync('stuff');
fs.rmdirSync('stuff');
fs.mkdir('stuff', () => {
fs.readFile('readMe.txt', 'utf8', (err, data) => {
fs.writeFile('./stuff/writeMe.txt', data, (err) => {})
})
})
fs.unlink('./stuff/writeMe.txt', () => {})
fs.rmdir('stuff', () => {})//必须是空文件夹