Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
浏览器中的JavaScript
Node.js 中的JavaScript
构建在Chrome的V8引擎之上
Node.js uses an eventt-driven, non-blocking I/O model that makes it lightweight and efficient
Node.js’ package ecosystem, npm, is the largest ecosystem of open source libaraies in the world.
npm install jquery
Web服务器后台
命令行工具
对于前端开发工程师,接触node最多的是他的命令行工具
HTML
CSS
JavaScript
简单的命令行操作
具有服务器开发经验更佳
@import('文件路径')
@import
一样来引用加载JavaScript脚本文件1.创建编写JavaScript脚本文件
2.打开终端定位到脚本文件的目录
3.输入 node 文件名
执行对应的文件
注意:文件名不要使用 node.js
命名
解析执行 JavaScript
读写文件
http
最简单的 http 服务:
// 使用 node 构建一个 Web 服务器
// 在 node 中提供了一个核心模块:http
// http 这个模块的职责是帮你创建编写服务器
// 1.加载 http 核心模块
var http = require('http');
// 2.使用 http.createServer() 方法创建一个 Web 服务器
// 返回一个Server实例
var server = http.createServer();
// 3.服务器提供对数据的服务
/*发请求
* 接收请求
* 处理请求
* 给个反馈(发送响应)
* 注册 requset 请求事件
* 当客户端请求过来,就会自动触发服务器的 request 请求事件,然后执行第二个参数:回调处理函数
*/
server.on('request', function () {
console.log('收到客户端请求');
})
// 4.绑定端口号,启动服务器
server.listen(3000, function () {
console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 访问')
});
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jEpmIFDF-1575955038352)(C:\Users\89349\AppData\Roaming\Typora\typora-user-images\1574495523937.png)]
node 为 JavaScript 提供了很多服务器级别的 API,这些 API 绝大多数都被包装到了一个具名的核心模块中。
例如:文件操作的 fs
核心模块,http 服务构建的 http
模块,path
路径操作模块,os
操作系统信息模块。
只要说这个模块是一个核心模块,就必须要使用它
var fs = require('fs')
var http = require('http')
http://tool.oschina.net/
使用 node 编写应用程序主要使用:
在 node 中的 JavaScript 还有一个重要的概念:模块系统
require
语法:
var 自定义变量名称 = require('模块');
两个作用:
exports
导出接口对象exports
node 中是模块作用域,默认文件中所有的成员只在当前文件
对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到 exports
接口对象中就可以了
导出多个成员(必须在对象中):
exports.a = 123;
exports.b = 'hello';
exports.c = function () {
console.log('ccc');
}
exports.d = {
foo : 'bar'
}
导出单个成员(拿到的就是:函数、字符串):
module.exports = 'hello';
以下情况还会覆盖:
// 一个模块需要直接导出某个成员
module.exports = 'hello';
// 后者会覆盖前者
module.exports = function (x, y) {
return x + y;
}
也可以这样导出多个成员:
module.exports = {
add: function (x, y) {
return x + y;
},
str: 'hello'
}
exports 和 module.exports
的一个引用
console.log(exports === module.exports); // => true
exports.foo = 'bar';
// 等价于
module.exports.foo = 'bar';
每个模块中都有一个 module 对象
module 对象中有一个 exports 对象
我们可以把需要导出的成员都挂载到 module.exports 接口对象中
也就是:moudle.exports.xxx = xxx
的方式
但是每次都 moudle.exports.xxx = xxx
很麻烦,点儿的太多了
所以 Node 为了你方便,同时在每一个模块中都提供了一个成员叫:exports
exports === module.exports
结果为 true
s
所以对于:moudle.exports.xxx = xxx
的方式 完全可以:expots.xxx = xxx
当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx
的方式
不要使用 exports = xxx
不管用
因为每个模块最终向外 return
的是 module.exports
而 exports
只是 module.exports
的一个引用
所以即便你为 exports = xx
重新赋值,也不会影响 module.exports
但是有一种赋值方式比较特殊:exports = module.exports
这个用来重新建立引用关系的
之所以让大家明白这个道理,是希望可以更灵活的去用它
Node 是一个比肩 Java、PHP 的一个平台
moudle.exports = {
a: 123
}
// 重新建立 exports 和 module.exports 之间的引用关系
exports = module.exports
exports.foo = 'bar'
Array.prototype.mySlice = function () {
var start = 0
var end = this.length
if (arguments.length === 1) {
start = arguments[0]
} else if (arguments.length === 2) {
start = arguments[0]
end = arguments[1]
}
var tmp = []
for (var i = start; i < end; i++) {
// fakeArr[0]
// fakeArr[1]
// fakeArr[2]
tmp.push(this[i])
}
return tmp
}
var fakeArr = {
0: 'abc',
1: 'efg',
2: 'haha',
length: 3
}
// 所以你就得到了真正的数组。
[].mySlice.call(fakeArr)
核心模块
第三方模块
用户自己写的
优先从缓存中加载
判断模块标识符
blog
a
node_modules
b
main.js
// b 加载不到 node_modules
npmjs.com
npm 的第二层含义就是一个命令行工具,只要安装了 node 就已经安装了 node。
npm 也有版本概念。
可以通过在命令行输入:
npm --version
升级 npm:
npm install --global npm
npm init
npm install
npm install 包名
npm install --save
npm uninstall 包名
npm uninstall --save 包名
npm help
npm 命令 --help
npm uninstall --help
来查看使用帮助npm 存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决。
http://npm.taobao.org/ 淘宝的开发团队把 npm 在国内做了一个备份。
安装淘宝的 cnpm:
# 在任意目录下执行都可以
# --global 表示安装到全局
# --global 不能省略
npm install --global cnpm
接下来你安装包的时候把之前的 npm
替换成 cnpm
。
举个例子:
# 这里还是走国外的 npm 服务器,速度比较慢
npm install jquery
# 使用 cnpm 就会通过淘宝的服务器来下载 jquery
cnpm install jquery
如果不想安装 cnpm
又想使用淘宝的服务器来下载:
npm install jquery --registry=https://registry.npm.taobao.org
每次添加参数和麻烦,可以把这个选项添加到配置文件中:
npm config set registry https://registry.npm.taobao.org
# 查看 npm 配置信息
npm config list
只要经历了上面的命令配置,则以后所有的 npm install
都会默认通过淘宝的服务器来下载。
我们建议每一个项目都要有一个 package.json
文件(包描述文件,就像产品的说明书一样)
这个文件可以通过 npm init
的方式来自动初始化出来。 直接生成(npm init -y
)
PS H:\前端-19\14nodejs(7天)\mytest_node\day03\npm-pack> npm init This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (npm-pack)
version: (1.0.0) 0.0.1
description: 这是一个测试项目
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: Mr.Zhang
license: (ISC)
About to write to H:\前端-19\14nodejs(7天)\mytest_node\day03\npm-pack\package.json:
{
"name": "npm-pack",
"version": "0.0.1",
"description": "这是一个测试项目",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Mr.Zhang",
"license": "ISC"
}
Is this OK? (yes) yes
PS H:\前端-19\14nodejs(7天)\mytest_node\day03\npm-pack> npm install --save jquery
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN npm-pack@0.0.1 No repository field.
+ jquery@3.4.1
added 1 package from 1 contributor and audited 1 package in 13.807s
found 0 vulnerabilities
对于我们来讲,最有用的就是 dependencies
选项,可以用来帮助我们保存第三方包的依赖信息。
如果你的 node_modules
删除了也不必担心,只需要:npm install
就会自动把 package.json
中的 dependencies
中的所有的依赖项都下载下来。
package.json
文件npm install 包名
的时候都加上 --save
用来保存依赖项信息npm5 以前没有 package-lock,json
这个文件。
npm5 以后才加入了这个文件。
当你安装包的时候, npm 都会生成或更新 package-lock.json
这个文件。
npm5 以后的版本安装包不需要加 --save
参数,它会自动保存依赖信息。
当你安装包的时候,会自动创建或者更新 package-lock.json
这个文件。
package-lock.json
这个文件会保存 node_modules
中所有包的信息(版本、下载地址)
npm install
从文件来看,有一个 lock
称之为锁
lock
是为了锁定版本1.1.1
版本1.1.1
这个版本package-lock.json
这个文件的另一个左右就是锁定版本号,防止升级成新版本在每个模块中,除了 require
、exports
等模块相关 API 之外,还有两个特殊的成员:
__dirname
动态获取 可以用来获取当前文件模块所属目录的绝对路径__filename
动态获取 可以用来获取当前文件的绝对路径__dirname
和 __filename
不受执行 node 命令所属路径影响的在文件操作中,使用相对路径不可靠,以为在 node 中文件操作的路径被设计为相对于对于执行 node 命令所处的路径(不是 bug)。
为了解决这个问题,使用绝对路径。
使用 __dirname
或者 __filename
来帮助解决问题。
结合 path.join()
path.join(__dirname, './a.txt')
补充:模块的路径标识和这里的路径没有关系
原生的 http 在某些方面表现不足以应对我们的开发需求,所以我们使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码高度统一。
在 node 中,有很多 Web 开发框架,学习 express
为主。
npm install --save express
var express = require('express');
// 1. 创建 app
var app = express();
app.get('/', function (req, res) {
// res.write('hello ');
// res.write('你好');
// res.end();
// res.end('hello world');
res.send('hello world');
// res.send('hello 你好');
})
app.listen(3000, function () {
console.log('express running·····');
});
路由器
get:
// 当你以 get 方法请求 / 的时候,执行对应的处理函数
app.get('/', function (req, res) {
res.send('Hello World!')
})
post:
// 当你以 post 方法请求 / 的时候,执行对应的处理函数
app.post('/', function (req, res) {
res.send('Hello World!')
})
// 当以 /public/ 开头的时候,去 ./public/ 目录中去找对应的资源
app.use('/public', express.static('./public/'));
//
// 当省略第一个参数的时候,则可以通过省略 /public 的方式访问
app.use(express.static('./public/'));
//
// 必须是 /a/public目录中的资源名称
// a 相当于 public 的别名
app.use('/a', express.static('./public/'));
app.use('/public', express.static(path.join(__dirname, 'public')))
art-template
模板引擎安装:
npm install --save art-template
npm install --save express-art-template
配置:
app.engine('html', require('express-art-template'));
使用:
app.get('/', function (req, res) {
// express 默认会去项目中的 views 目录中找 index.html
res.render('index.html', {
title: 'hello'
})
})
如果希望修改默认的 views
视图渲染存储目录,可以:
// 注意:第一个参数 views 不能写错
app.set('views', 目录路径)
Express 内置了一个 API,可以直接通过 req.query
来获取。
req.query
在 Express 中没有内置获取表单 POST 请求体的 API,我们需要使用一个第三方包:body-parser
。
安装:
npm install --save body-parser
配置:
var express = require('express')
// 1. 引包
var bodyParser = require('body-parser')
var app = express()
// 配置 body-parser
// 只要加入这个配置,则在 req 请求对象上会多出来一个属性:body
// 通过 req.body 来获取表单 POST 请求体数据
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: false }))
// parse application/json
app.use(bodyParser.json())
使用:
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
// 可以通过 req.body 来获取表单 POST 请求体数据
res.end(JSON.stringify(req.body, null, 2))
})
express-session
插件参考文档:https://www.npmjs.com/package/express-session
安装:
npm install express-session
配置:
// 在 Express 这个框架中,默认不支持 Session 和 Cookie
// 但是我们可以使用第三方中间件:express-session 来解决
// 1. npm install express-session
// 2. 配置(一定要在路由挂载之前)
// 3. 使用
// 当把这个插件配置好之后,我们就可以通过 req.session 来访问和设置 session 成员
// 添加 session 数据 req.session.foo = 'bar'
// 访问 session 数据 req.session.foo
app.use(session({
// 配置加密字符串 --- 会在原有加密基础上和这个字符串拼接起来加密
// 目的是为了增强安全性,防止客户端恶意伪造
secret: 'keyboard cat',
resave: false,
saveUninitialized: true // 无论你是否使用 session,我都直接给你分配一把钥匙
}))
使用:
// 添加 session 数据
req.session.foo = 'bar'
// 获取 session 数据
req.session.foo
提示:默认 session 数据是内存存储的,服务器一旦重启就会丢失,真正的生产环境会把 session 进行持久化存储。
请求方法 | 请求路径 | get 参数 | post 参数 | 备注 |
---|---|---|---|---|
GET | /students | 渲染首页 | ||
GET | /students/new | 渲染添加学生页面 | ||
POST | /students/new | name、age、gender、hobbies | 处理添加学生请求 | |
GET | /students/edit | id | 渲染编辑页面 | |
POST | /students/edit | id、name、age、gender、hobbies | 处理编辑请求 | |
GET | /students/delete | id | 处理删除请求 |
router.js:
/**
* router.js 路由模块
* 职责:
* 处理路由
* 根据不同的请求方法+请求路径设置具体的请求处理函数
*/
var fs= require('fs')
// Express 提供了一种更好的方式
// 专门用来包装路由的
var express = require('express')
// 1. 创建一个路由容器
var router = express.Router()
// 2. 把路由都挂载到 Router 容器中
router.get('/students', function (req, res) {
// readFile 的第二个参数是可选的,传入 utf8 就是告诉他把读取到的文件直接按照 utf8 编码转成我们能认识的字符
// 除了这样来转换之外,也可以通过 data.toString() 的方式
fs.readFile('./db.json', 'utf8', function (err, data) {
if (err) {
return res.status(500).send('Server error')
}
// 从文件中读取到的数据一定是字符串
// 所以这里一定要手动转换成对象
var students = JSON.parse(data).students
res.render('index.html', {
fruits: [
'苹果',
'香蕉',
'火龙果'
],
students: students
})
})
})
router.get('/students/new', function (req, res) {
res.render('new.html')
})
router.post('/students/new', function (req, res) {
// 1. 获取表单数据
// 2. 处理
// 将数据保存到 db.json,持久化
// 3. 发送响应
// 先读取出来,转成对象
// 然后往对象中 push 数据
// 然后把对象转为字符串
// 然后把字符串再次写入文件
console.log(req.body)
})
router.get('/students/edit', function (req, res) {
})
router.post('/studens/edit', function (req, res) {
})
router.get('/students/delete', function (req, res) {
})
// 3. 把 router 导出
module.exports = router
app.js:
var router = require('./router')
// 挂载路由
app.use(router)
student.js:
/**
* student.js
* 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
*/
/**
* 获取所有学生列表
* return []
*/
exports.find = function () {
}
/**
* 添加保存学生
*/
exports.save = function () {
}
/**
* 更新学生
*/
exports.update = function () {
}
/**
* 删除学生
*/
exports.delete = function () {
}
表与表之间存在关系
sql
语言来操作64位下载地址:https://www.mongodb.com/download-center/community
下载
安装
配置环境变量
输入 mongod --version
测试是否安装成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4zXKNiW-1575955038354)(C:\Users\89349\AppData\Roaming\Typora\typora-user-images\1575610504849.png)]
启动:
# mongodb 默认使用执行 mongod 命令所处盘符根目录下的 /data/db 作为自己的数据存储目录
# 所以在第一次执行该命令之前先自己手动新建一个 /data/db
mongod
如果想要修改默认的数据存储目录,可以:
mongod --dbpath=数据存储目录路径
停止:
在开启服务的控制台,直接 ctrl + c 即可停止
或者直接关闭开启服务的控制台
连接:
# 该命令默认连接本机的 mongodb 服务
mongo
退出:
# 在连接状态输入
exit
show dbs
db
use 数据库名称
插入数据
mongodb
包使用https://www.npmjs.com/package/mongodb
第三方包:mongoose
基于 MongoDB 官方的 mongodb
包做了封装
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
const Cat = mongoose.model('Cat', {
name: String });
const kitty = new Cat({
name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
var mongoose = require('mongoose')
var Schema = mongoose.Schema
// 1. 连接数据库
mongoose.connect('mongodb://localhost/itcast');
// 2. 设计文档结构(表结构)
// 字段名称就是表结构中的属性名称
// 值
// 约束的目的是为了保证数据的完整性,不要有脏数据
var userSchema = new Schema({
username: {
type: String,
required: true // 不能为空
},
password: {
type: String,
required: true
},
email: {
type: String
}
});
// 3. 将文档结构发布为模型
// mongoose.model 方法就是用来将一个架构发布为 model
// 第一个参数:传入一个大写名词单数字符串用来表示你的数据库名称
// mongoose 会自动将大写名称的字符串生成 小写复数 的集合名称
// 例如 User ---> users
// 第二个参数:构架 Schema
//
// 返回值:模型构造函数
var User = mongoose.model('User', userSchema)
// 4. 当我们有了模型构造函数之后,就可以使用这个构造函数对 users 集合中的数据进行 增、删、改、查
/**
* 新增数据
* @type {User}
*/
var admin = new User({
username: 'root',
password: '789',
email: '[email protected]'
})
admin.save(function (err, ret) {
if (err) {
console.log('保存失败')
} else {
console.log('保存成功')
console.log(ret)
}
})
// =====================================================
/**
* 查询所有数据
* @param {[type]} err [description]
* @param {[type]} ret) { if (err) { console.log('查询失败') } else { console.log(ret) }} [description]
* @return {[type]} [description]
*/
User.find(function (err, ret) {
if (err) {
console.log('查询失败')
} else {
console.log(ret)
}
})
/**
* 按照条件查询
* @param {[type]} err [description]
* @param {[type]} ret) { if (err) { console.log('查询失败') } else { console.log(ret) }} [description]
* @return {[type]} [description]
*/
User.find({
username: 'root'
},function (err, ret) {
if (err) {
console.log('查询失败')
} else {
console.log(ret)
}
})
/**
* 查询第一个符合条件的数据,数据类型是----对象
* @param {[type]} err [description]
* @param {[type]} ret) { if (err) { console.log('查询失败') } else { console.log(ret) }} [description]
* @return {[type]} [description]
*/
User.findOne({
username: 'admin'
},function (err, ret) {
if (err) {
console.log('查询失败')
} else {
console.log(ret)
}
})
// =====================================================
/**
* 删除数据(按条件)
* @param {[type]} err [description]
* @param {[type]} ret) { if (err) { console.log('删除失败') } else { console.log('删除成功') console.log(ret) }} [description]
* @return {[type]} [description]
*/
User.remove({
username: 'root'
},function (err, ret) {
if (err) {
console.log('删除失败')
} else {
console.log('删除成功')
console.log(ret)
}
})
// =====================================================
/**
* 更新数据(按条件)
* @param {[type]} err [description]
* @param {[type]} ret) { if (err) { console.log('更新失败') } else { console.log('更新成功') console.log(ret) }} [description]
* @return {[type]} [description]
*/
User.findByIdAndUpdate('5deb06ead567bd38505d5db3', {
password: 'what'
}, function (err, ret) {
if (err) {
console.log('更新失败')
} else {
console.log('更新成功')
console.log(ret)
}
})
callback hell
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-piwFgZUP-1575955038354)(C:\Users\89349\Desktop\u=2529250617,3283018274&fm=26&gp=0.jpg)]
无法保证顺序的代码
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
通过回调嵌套的方式来保证代码的执行顺序
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('读取失败')
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
})
})
为了解决回调地狱的嵌套,EcmaScript 6 中新增了一个 API:Promise
。
Promise
本身不是异步的。
var fs = require('fs')
// EcmaScript 6 中新增了一个 API Promise
// Promise 是一个构造函数
// console.log(1)
// 创建 Promise 容器
// Promise 一旦创建,就开始执行里面的代码
var p1 = new Promise(function (resolve, reject) {
// console.log(2)
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// 失败了,承诺容器中的任务失败了
// console.log(err)
// 把容器的 Pending 状态变成 Reject
//
// 调用 reject 就相当于调用了 then 方法中的第二个函数
reject(err)
} else {
// console.log(3)
// 承诺容器中的任务成功了
// console.log(data)
// 把容器的 Pending 状态变成 Resolved
// 这里调用的 resolve 方法实际上就是 then 方法传递的那个 function
resolve(data)
}
})
})
var p2 = new Promise(function (resolve, reject) {
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p3 = new Promise(function (resolve, reject) {
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
// p1 就是那个承诺
// 当 p1 成功了,然后(then)做指定的操作
// then 方法接收的 function 就是容器中的 resolve
p1
.then(function(data) {
console.log(data)
// 当 p1 读取成功的时候
// 当前函数中的 return 的结果就可以在后面的 then 中 function 接收到
// 当你 return 123 后面接收到的就是 123
// 没有return 接收到的就是 undefined
//
// 真正要 return 的是一个 Promise 对象
// 当 return 一个 Promise 对象的时候,后续的 then 中的方法的第一个参数会作为 p2 的 resolve
return p2
}, function(err) {
console.log('读取文件失败了', err)
})
.then(function(data) {
console.log(data)
return p3
}, function(err) {
console.log('读取文件失败', err)
})
.then(function(data) {
console.log(data)
}, function(err) {
console.log('读取文件失败', err)
})
封装 Promise 版本的 readFile
var fs = require('fs')
function pReadFile(filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
pReadFile('./data/a.txt')
.then(function (data) {
console.log(data)
return pReadFile('./data/b.txt')
})
.then(function (data) {
console.log(data)
return pReadFile('./data/c.txt')
})
.then(function (data) {
console.log(data)
})
function get(url, callback) {
var oReq = new XMLHttpRequest();
oReq.onload = function(e) {
var arraybuffer = oReq.response; // not responseText
/* ... */
callback(oReq.response)
}
oReq.open("GET", url);
oReq.send();
}
get('data.json', function(data) {
console.log(data)
})
可以使用第三方工具: nodemon
帮助我们解决频繁修改代码重启服务器的问题。
nodemon
是一个基于 node.js 开发的一个第三方命令行工具,我们使用的时候需要独立安装:
# 在任意目录执行该命令都可以
npm install --global nodemon
安装完毕之后,使用:
node app.js
# 使用 nodemon
nodemon app.js
只要是通过 nodemon app.js
启动的服务,则它会监视你的文件变化,当文件发生变化时,自动帮你重启服务器。
文件操作路径:
// 在文件操作的相对路径中
// ./data/a.txt 相对于当前目录
// data/a.txt 相对于当前目录
// /data/a.txt 绝对路径,当前文件模块所处磁盘根目录
// h:/xx/xx.. 绝对路径
fs.readFile('/data/a.txt', function (err, data) {
if (err) {
return console.log(err);
}
console.log(data.toString());
})
模块操作路径:
// 这里的 / 也是磁盘根路径
require('/data/foo.js')
// 相对路径
require('./data/foo.js')
// 模块加载的路径中的相对路径 ./ 不能省略
t(err)
} else {
resolve(data)
}
})
})
}
pReadFile(’./data/a.txt’)
.then(function (data) {
console.log(data)
return pReadFile(’./data/b.txt’)
})
.then(function (data) {
console.log(data)
return pReadFile(’./data/c.txt’)
})
.then(function (data) {
console.log(data)
})
### 其他
***
#### 基于原生 XMLHttpRequest 封装 get 方法
```javascript
function get(url, callback) {
var oReq = new XMLHttpRequest();
oReq.onload = function(e) {
var arraybuffer = oReq.response; // not responseText
/* ... */
callback(oReq.response)
}
oReq.open("GET", url);
oReq.send();
}
get('data.json', function(data) {
console.log(data)
})
可以使用第三方工具: nodemon
帮助我们解决频繁修改代码重启服务器的问题。
nodemon
是一个基于 node.js 开发的一个第三方命令行工具,我们使用的时候需要独立安装:
# 在任意目录执行该命令都可以
npm install --global nodemon
安装完毕之后,使用:
node app.js
# 使用 nodemon
nodemon app.js
只要是通过 nodemon app.js
启动的服务,则它会监视你的文件变化,当文件发生变化时,自动帮你重启服务器。
文件操作路径:
// 在文件操作的相对路径中
// ./data/a.txt 相对于当前目录
// data/a.txt 相对于当前目录
// /data/a.txt 绝对路径,当前文件模块所处磁盘根目录
// h:/xx/xx.. 绝对路径
fs.readFile('/data/a.txt', function (err, data) {
if (err) {
return console.log(err);
}
console.log(data.toString());
})
模块操作路径:
// 这里的 / 也是磁盘根路径
require('/data/foo.js')
// 相对路径
require('./data/foo.js')
// 模块加载的路径中的相对路径 ./ 不能省略