NODE.js five day
- Express
- MongoDB
- 项目
零散knowledge
- submit的快捷操作方式
选中字符 crtl + d : 选择同样的字符
ctrl + shift + d : 复制内容
ctrl + alt + 左右键选中字符,遇到空格会划分
插件 HTML -css - js prettify
Callback
-
函数也是一种数据类型,它和其他数据类型一样,既可以当做参数进行传递,也可以当做方法的返回值使用
-
php 里为什么能直接使用require include呢,因为php在设计初已经加入了这些功能
-
模块作用域
-
可以使用 API 来进行文件与文件之间的依赖加载
-
在 Node 这个环境中对 JavaScript 进行了特殊的模块化支持 CommonJS
-
JavaScript 天生不支持模块化
- require
- exports
- Node.js 才有的
-
在浏览器中也可以像在 Node 中的模块一样来进行编程
<script>
标签来引用加载,而且你还必须考虑加载的顺序问题- require.js 第三方库 AMD
- sea.js 第三方库 CMD
-
无论是 CommonJS、AMD、CMD、UMD、EcmaScript 6 Modules 官方规范
-
都是为了解决 JavaScript 的模块化问题
-
CommonJS、AMD、CMD 都是民间搞出来的
-
EcmaScript 是官方规范定义
-
官方看民间都在乱搞,开发人员为了在不同的环境使用不同的 JavaScript 模块化解决方案
-
所以 EcmaScript 在 2015 年发布了 EcmaScript 2016 官方标准
-
其中就包含了官方对 JavaScript 模块化的支持
-
也就是说语言天生就支持了
-
但是虽然标准已经发布了,但是很多 JavaScript 运行换将还不支持
-
Node 也是只在 8.5 版本之后才对 EcmaScript 6 module 进行了支持
-
后面学 Vue 的时候会去学习
-
less 编译器 > css
-
EcmaScript 6 -> 编译器 -> EcmaScript 5
-
目前的前端情况都是使用很多新技术,然后利用编译器工具打包可以在低版本浏览器运行。
-
使用新技术的目的就是为了提高效率,增加可维护性
-
有时候浏览器无法正确显示效果,就去清楚缓存
-
引入bodyapi
/**
* app.js 入门模块
* 职责:
* 创建服务
* 做一些服务相关配置
* 模板引擎
* body-parser 解析表单 post 请求体
* 提供静态资源服务
* 挂载路由
* 监听端口启动服务
*/
var express = require('express')
var router = require('./router')
var bodyParser = require('body-parser')
var app = express()
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))
app.engine('html', require('express-art-template'))
// 配置模板引擎和 body-parser 一定要在 app.use(router) 挂载路由之前
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// 把路由容器挂载到 app 服务中
app.use(router)
app.listen(3000, function () {
console.log('running 3000...')
})
module.exports = app
回调函数 : 异步编程
// 注意:凡是需要得到一个函数内部异步操作的结果
// setTimeout
// readFile
// writeFile
// ajax
// 这种情况必须通过:回调函数
不成立的情况
function add(x,y){
console.log(1)
setTimeout(function(){
console.log(2)
var ret = x + y
return ret
},1000)
console.log(3)
//到这来就结束了,不会等到前面的定时器,所以直接返回undefined
}
console.log(add(10,20)) //undefined
</script> `
`<script>
function add(x, y, callback) {
console.log(1)
setTimeout(function () {
var ret = x + y
callback(ret)
}, 1000)
}
add(10, 20, function (ret) {
console.log(ret)
})
</script>`
###封装ajax
- 涉及异步编程的情况
- setTimeout
- readFile
- writeFile
- readdir
- ajax
- 正常来说 异步api都伴随一个回调函数
ajax的异步刷新,传统的方式是客户端向服务端发送请求,服务端接收处理后返回一个新
的html,现在是通过ajax请求回一串字符串并局部渲染到页面中去。
`<script>
function get(url,callback){
var oReq = new XMLHttpRequest()
// 当请求加载成功之后需要用到回调函数
oReq.onload = function(){
callback(oReq.responseText)
}
oReq.open("get",url,true)
oReq.send()
}
get('data.json',function(data){
console.log(data)
})
//传入的是json格式的数据
###package-lock.json
关于npm配置文件的依赖文件
npm 5 以后才有的package-lock.json
在npm init -S y 后安装其他包就会默认生成lock
顾名思义,就是锁定配置文件信息。
防止所依赖的配置module文件丢失后下载繁忙和版本不对应的情况。
###find方法
<script> // EcmaScript 6 对数组新增了很多方法 // find // findIndex // find 接收一个方法作为参数,方法内部返回一个条件 // find 会遍历所有的元素,执行你给定的带有条件返回值的函数 // 符合该条件的元素会作为 find 方法的返回值 // 如果遍历结束还没有符合该条件的元素,则返回 undefined var users = [ {id: 1, name: '张三'}, {id: 2, name: '张三'}, {id: 3, name: '张三'}, {id: 4, name: '张三'} ] Array.prototype.myFind = function (conditionFunc) { // var conditionFunc = function (item, index) { return item.id === 4 } for (var i = 0; i < this.length; i++) { if (conditionFunc(this[i], i)) { return this[i] } } } var ret = users.myFind(function (item, index) { return item.id === 2 }) console.log(ret) </script>
上午总结
- 回调函数
- 异步编程
- 如果需要得到一个函数内部异步操作的结果,这是时候必须通过回调函数来获取
- 在调用的位置传递一个函数进来
- 在封装的函数内部调用传递进来的函数
- find、findIndex、forEach
- 数组的遍历方法,都是对函数作为参数一种运用
- every
- some
- includes
- map
- reduce
- 数组的遍历方法,都是对函数作为参数一种运用
- package-lock.json 文件的作用
- 下载速度快了
- 锁定版本
- JavaScript 模块化
- Node 中的 CommonJS
- 浏览器中的
- AMD require.js
- CMD sea.js
- EcmaScript 官方在 EcmaScript 6 中增加了官方支持
- EcmaScript 6
- 后面我们会学,编译工具
- MongoDB 数据库
- MongoDB 的数据存储结构
- 数据库
- 集合(表)
- 文档(表记录)
- MongoDB 的数据存储结构
- MongoDB 官方有一个 mongodb 的包可以用来操作 MongoDB 数据库
- 这个确实和强大,但是比较原始,麻烦,所以咱们不使用它
- mongoose
- 真正在公司进行开发,使用的是 mongoose 这个第三方包
- 它是基于 MongoDB 官方的 mongodb 包进一步做了封装
- 可以提高开发效率
- 让你操作 MongoDB 数据库更方便
- 掌握使用 mongoose 对数据集合进行基本的 CRUD
- 把之前的 crud 案例改为了 MongoDB 数据库版本
- 使用 Node 操作 mysql 数据库
###关系型数据库和非关系型数据库
表就是关系
- 所有关系型数据库都需要通过mysql语言来操作
- 都需要设计表结构
- 数据表还支持约束
- 唯一的
- 主键
- 默认值
- 非空
- 非关系型数据库非常灵活
- 有的就是key-value对
- mongodb是长得最像关系型数据库的非关系型数据库
- 数据库 - 数据库
- 数据表 - 集合
- 表记录 - 文档对象
- mongodb 不需要设计表结构
- 配置环境
- mongod --version
参考 http://www.runoob.com/mongodb/mongodb-tutorial.html
###Ajax的封装方法
回调函数是在异步数据操作的时候使用,用于把函数内部想要的结果让外部能够访问。
SetTimeout readFile wirteFile readdir 都是异步数据操作。
https://jingyan.baidu.com/article/49711c61711015fa451b7c42.html
###mongodb安装
mongodb –version 只能在安装目录,有mongod.exe目录下进行,
修改data目录不实际,运行cmd mongod查看他的data目录是在什么位置
在目标位置创建数据文件夹就OK 然后在cmd、运行服务
Mongod 没有任何表结构,任何数据集都没限制,怎么写怎么存
但是为了规范自己得添加一些条件关系来约束
如果想要更改默认数据目录
-
- mongodb --dbpath = 数据存储目录路径
- 停止: 直接关闭控制台
- 启动: mongod
- 链接: mongo
- 退出: exit
- 基本命令
show dbs : 查看显示所有数据库
db : 查看对当前操作的数据库
use + 数据库名称 : 切换到指定数据,如果没有数据库就自动创建
插入数据 :
查看: show collection
遍历: db.student。find()
根据条件: ab.student.insertOne({“name”:“jack”})
//也就是json格式数据
###初始化mongodb
在guith或者 www.npmjs.com 上查资料
- 首先安装 官方mongob包来操作
- 使用第三方mongoose来操作mongodb数据库,他是根据mongob进行封装的。
npm i mongoose
<script> var mongoose = require('mongoose'); // 连接 MongoDB 数据库 mongoose.connect('mongodb://localhost/test', { useMongoClient: true }); mongoose.Promise = global.Promise; // 创建一个模型 // 就是在设计数据库 // MongoDB 是动态的,非常灵活,只需要在代码中设计你的数据库就可以了 // mongoose 这个包就可以让你的设计编写过程变的非常的简单 var Cat = mongoose.model('Cat', { name: String }); for (var i = 0; i < 100; i++) { // 实例化一个 Cat var kitty = new Cat({ name: '喵喵' + i }); // 持久化保存 kitty 实例 kitty.save(function (err) { if (err) { console.log(err); } else { console.log('meow'); } }); } </script>
mongodb数据库的基本概念
- 可以有多个数据库
- 一个数据库中可以有多个集合(表)
- 文档结构很灵活,没有任何限制,数据结构和json数据格式无差
- mongodb非常灵活,不需要想mysql一样先创建数据库表设计表结构
- 只需要在你插入数据的时候,只需要指定往哪个数据库的哪个集合
mongodb开始
var mongoose = require('mongoose')
//数据结构
var Schema = mongoose.Schema
//1.链接指定数据库
//如果数据库不存在,则在你插入第一条数据以后自己被创建出来
mongoose.connect('mongodb://localhost/库名')
//2.设计文档结构(表结构)
//字段名称就是表结构的属性名称
// 约束的目的是为了保证数据的完整性,不要有脏数据
var userSchema = new Schema({
username :{
type : String,
required: true //必须
}
password:{
type : String,
required : true
}
email : {
type : String,
}
//3.将文档结构发布为模型
mongoose.model 方法就是用来将一个框架发布为 model
第一个参数 : 传入一个大写名词单数字符串用来表示你的数据库名称
mongoose 会自动将大学名词的字符串生成小写复数的集合名称
第二个参数: 架构 Schema
返回值 : 模型结构函数
var User = mongoose.model('User',userSchema)
// 4. 有了模型构造函数之后,就可以对user集合进行增删改查
************************************
user新增数据:
var admin = new User({
username : 'zc',
password : 'czc',
email : 'czc@czc.czc'
})
//持久化
admin.save(function(err,ret){
if(err){
console.log('save faile')
}else{
console.log('save success')
console.log(ret)
}
})
*************************************
查询数据:
<!-- User.find(function (err, ret) {
if(err){
console.log('查询失败')
} else {
console.log(ret)
}
}) -->
User.find({
username : 'zc'
},function(err,ret){
if(err){
console.log('查询失败')
} else {
console.log(ret)
}
})
User.findOne({
username : 'zc'
},function(err,ret){
if(err){
console.log('查询失败')
} else {
console.log(ret)
}
})
****************************
删除数据:
User.remove({
username : 'zc'
},function(){
if (err) {
console.log('删除失败')
} else {
console.log('删除成功')
console.log(ret)
}
})
****************************
更新数据 :
User.findByIdAndUpdate('获取的id的加密值',{
password : '123'
},function(err,ret){
if (err) {
console.log('更新失败')
} else {
console.log('更新成功')
}
})
*********************************
})
###使用node操作mysql数据库
###回调地狱
以为readFile是异步操作,执行顺序取决余读取文件的大小,并不会等来上边的执行后再折行下一步的。
因为throw err 返回结果后,再直接折行下一个,所以才不会打乱顺序
<script> 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) }) }) }) </script>
- 为了解决上面回调嵌套的问题
再es6中新增了一个api : promise 意思是保证的意思
var fs = require('fs')
//promise 是一个构造函数
//1.创建promise容器
promise容器一旦创建,就开始折行里面的代码
p1 = new promise(function(resolve,reject){
fs.readFile('./dataatxt','utf-8',function(err,data){
if(err){
//console.log(err)
//把容器的pending状态变为rejected
reject(err)
}else{
console.log(data)
resolve(data)
}
}
})
p1
.then(function(data){
console.log(data)
//当p1成功时,当前函数中的return的结果就是后面的then中的function接收到
return p2
},function(err){
console.log('读取失败',err)
})
.then(function(data){
console.log(data)
//这里的data就是p2
})
- 多嵌套
var fs = require('fs')
var p1 = new Promise(function (resolve, reject) {
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
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
.then(function (data) {
console.log(data)
// 当 p1 读取成功的时候
// 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
// 当你 return 123 后面就接收到 123
// return 'hello' 后面就接收到 'hello'
// 没有 return 后面收到的就是 undefined
// 上面那些 return 的数据没什么卵用
// 真正有用的是:我们可以 return 一个 Promise 对象
// 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
//
return p2
}, function (err) {
console.log('读取文件失败了', err)
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
console.log('end')
})
- 封装 promise api
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)
})