nodejs个人学习笔记

node

node day2

1. express 基本使用
//引包
var express = require('express');
//创建server 服务器
var app = express();

app.get('/',function (request,responset) {	
		responset.send('你好 hello express!')
})
app.listen('3000',function () {
	console.log('server is running.....')
})
2. express 公开静态资源
// 当以 /public/ 开头的时候,去 ./public/ 目录中找找对应的资源
// 127.0.0.1:3000/public/index.html
 app.use('/public/', express.static('./public/'))

//  127.0.0.1:3000/abc/d/index.html
 app.use('/abc/d/', express.static('./public/'))
 
app.use(express.static(path.resolve(__dirname, '../dist')));

// 当省略第一个参数的时候,则可以通过 省略 /public 的方式来访问
// 这种方式的好处就是可以省略 /public/
// 127.0.0.1:3000/index.html
 app.use(express.static('./public/'))
3. 文件操作路径与模块操作路径

nodejs个人学习笔记_第1张图片

4.node修改完代码自动重启

通过第三方包命定行工具:nodemmon

nodemon是基于node.js 开发的第三方命令行工具

# 进行全局安装
npm install nodemon --global

安装后cmd运行即可

nodemon app.js

node day3

1.在express中配置使用 art-template

art-template: https://aui.github.io/art-template/zh-cn/docs/

  1. 安装

    npm install art-template --save
    npm install express-art-template --save
    
  2. 配置

    app.engine('html',require('express-art-template'))
    
  3. 使用

    app.get('/',function (require,response) {
        //express 默认会去项目中的 views 目录中找 index.html
        response.render('index.html', {
            title: 'hell world'
        })
    })
    
  4. 如果需要修改默认views 视图渲染储存目录,可以:

    app.set('views',目录名称)
    
art-template 模板继承

​ 1.模板页



<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Documenttitle>
  <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css">
  {{ block 'head' }}{{ /block }}  
head>
<body>
  {{ include './header.html' }}   
    
 
   
  {{ block 'content' }}   
    <h1>默认内容h1> 
  {{ /block }}

  {{ include './footer.html' }}  
  <script src="/node_modules/jquery/dist/jquery.js">script>
  <script src="/node_modules/bootstrap/dist/js/bootstrap.js">script>
  {{ block 'script' }}{{ /block }}
body>
html>

​ 页面子页 (孩子)


{{extend './layout.html'}}  

{{ block 'head' }}  

{{ /block }}

{{ block 'content' }}

index 页面填坑内容

{{ /block }} {{ block 'script' }} {{ /block }}
2.express GET方式获取数据
request.query
3.express POST方式获取数据

使用插件 body-parser

  1. 安装:

    npm install body-parser --save
    
  2. 配置:

    var express = require('express')
    var bodyParser = require('body-parser')
    var app = express()
    // parse application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({ extended: false }))
    // parse application/json
    app.use(bodyParser.json())
        
    
  3. 使用:

     //通过 request.body 来获取数据
    app.post('/pinglun',function (request,response) {
    	var newComments = request.body
    		newComments.dateTime = '2019-012-11'
    		comments.unshift(newComments)
    		response.redirect('/')
    })
    
    
4. fs.readFile 的第三个参数 及 获取文件内容渲染 art-template
app.get('/', function (request,response) {
			//fs.readFile 第二个参数 传 utf8 可以将文件内容通过utf-8 来编译
			//无需 在data.toString() 来转换
	fs.readFile('./db.json','utf8',function (error,data) {
		if (error) {
				// status ==> 状态码
			return response.status(500).send('server error...')
		}
		   //获取的是字符串 将其转换为对象 .students
		var students = JSON.parse(data).students
		response.render('index.html',{
			abc: ['张三','李四','王五'],
			students: students
		})
	})
	
}) 
5.路由模块的提取
  1. router.js 中创建路由容器
var fs = require('fs')

var express = require('express')

//1.创建一个路由容器
var router = express.Router()
//2.把路由挂载到 router 路由容器中
router.get('/', function (request,response) {
		response.send('hello node')
})  
//3.把 router 导出
module.exports = router
  1. app.js 中 把路由容器挂到 app 服务中

    //把路由容器挂到 app 服务中
    app.use(reouter)
    
    
6. express 中的中间件
  • 中间件的本质就是一个请求处理方式,我们用户请求到响应的整个流程发布到多个中间件去处理,这样做的目的是提高代码的灵活性,动态可扩展。
var express = require('express')

var app = express()

// 中间件:处理请求的,本质就是个函数

// 在 Express 中,对中间件有几种分类

// 当请求进来,会从第一个中间件开始进行匹配
//    如果匹配,则进来
//       如果请求进入中间件之后,没有调用 next 则代码会停在当前中间件
//       如果调用了 next 则继续向后找到第一个匹配的中间件
//    如果不匹配,则继续判断匹配下一个中间件
//    
// 不关心请求路径和请求方法的中间件
// 也就是说任何请求都会进入这个中间件
// 中间件本身是一个方法,该方法接收三个参数:
//    Request 请求对象
//    Response 响应对象
//    next     下一个中间件
// 当一个请求进入一个中间件之后,如果不调用 next 则会停留在当前中间件
// 所以 next 是一个方法,用来调用下一个中间件的
// 调用 next 方法也是要匹配的(不是调用紧挨着的那个)
/

  • 万能匹配 (不关心如何请求路径以请求方式)
 app.use(function (req, res, next) {
   console.log('1')
   next()  //执行下一个 满足要求的 
 })

  • 要求以 / 开头的
 app.use('/',function (req, res, next) {
   console.log('2')
   next()   
 })

  • 路由级别 中间件 要求以 get 方式 请求 /a
app.get('/a',function (request,response) {
    console.log(3)    
})

  • 第三方 中间件
    • cookie-session
    • body-parser
    • 其他
  • 同一个请求所经过d中间件都是同一个请求对象requert 和 响应对象response
app.get('/a',function (request,response,next) {
    var data = 123 ;
    next()
})

app.get('/a',function (request,response,next) {
   console.log(data)
})

  • 配置 全局错误处理中间件
app.get('/', function (req, res, next) {
  fs.readFile('.d/sa./d.sa/.dsa', function (err, data) {
    if (err) {
      // return res.status(500).send('Server Error')
      // 当调用 next 的时候,如果传递了参数,则直接往后找到带有 四个参数的应用程序级别中间件
      // 当发生错误的时候,我们可以调用 next 传递错误对象
      // 然后就会被全局错误处理中间件匹配到并处理之
      next(err)
    }
  })
})

// 配置错误处理中间件
//!!! 注意 !!! 错误处理中间件 必须  在 挂载路由 app.use(router) 之后  
app.use(router)

app.use(function (err, req, res, next) {
  res.status(500).send(err.message)
})

// 配置 404 中间件
app.use(function (request,response) {
    response.render(404.index)
})

7. 设计操作文件数据的API 模块 (增删改查)
/**
 * student.js
 * 数据操作文件模块
 * 职责:操作文件中的数据,只处理数据,不关心业务
 */
	
var fs = require('fs')

var dbPath = './db.json'

/**
 * 获取学生列表
 * @param  {Function} callback 回调函数
 */

exports.find = function (callback) {
	fs.readFile(dbPath,'utf8',function (error,data) {
		if(error){
			return callback(err)
		}
		callback(null,JSON.parse(data).students)
	})
}

/**
 * 添加学生列表
 * @param  {Object}   student  学生对象
 * @param  {Function} callback 回调函数
 */
exports.save = function (student, callback) {
  fs.readFile(dbPath, 'utf8', function (err, data) {
    if (err) {
      return callback(err)
    }
      //转成对象
    var students = JSON.parse(data).students

    // 添加 id ,唯一不重复
    student.id = students[students.length - 1].id + 1

    // 把用户传递的对象保存到数组中
    students.push(student)

    // 把对象数据转换为字符串
    var fileData = JSON.stringify({
      students: students
    })

    // 把字符串保存到文件中
    fs.writeFile(dbPath, fileData, function (err) {
      if (err) {
        // 错误就是把错误对象传递给它
        return callback(err)
      }
      // 成功就没错,所以错误对象是 null
      callback(null)
    })
  })
}

/**
 * 根据 id 获取学生信息对象
 * @param  {Number}   id       学生 id
 * @param  {Function} callback 回调函数
 */
exports.findById = function (id, callback) {
  fs.readFile(dbPath, 'utf8', function (err, data) {
    if (err) {
      return callback(err)
    }
    var students = JSON.parse(data).students
    var ret = students.find(function (item) {
      return item.id === parseInt(id)
    })
    callback(null, ret)
  })
}

/**
 * 更新学生
 */
exports.updateById = function (student, callback) {
  fs.readFile(dbPath, 'utf8', function (err, data) {
    if (err) {
      return callback(err)
    }
    var students = JSON.parse(data).students

    // 注意:这里记得把 id 统一转换为数字类型
    student.id = parseInt(student.id)

    // 你要修改谁,就需要把谁找出来
    // EcmaScript 6 中的一个数组方法:find
    // 需要接收一个函数作为参数
    // 当某个遍历项符合 item.id === student.id 条件的时候,find 会终止遍历,同时返回遍历项
    var stu = students.find(function (item) {
      return item.id === student.id
    })

    // 这种方式你就写死了,有 100 个难道就写 100 次吗?
    // stu.name = student.name
    // stu.age = student.age

    // 遍历拷贝对象
    for (var key in student) {
      stu[key] = student[key]
    }

    // 把对象数据转换为字符串
    var fileData = JSON.stringify({
      students: students
    })

    // 把字符串保存到文件中
    fs.writeFile(dbPath, fileData, function (err) {
      if (err) {
        // 错误就是把错误对象传递给它
        return callback(err)
      }
      // 成功就没错,所以错误对象是 null
      callback(null)
    })
  })
}

/*
 * 处理删除学生
 */
exports.deleteById = function (id, callback) {
  fs.readFile(dbPath, 'utf8', function (err, data) {
    if (err) {
      return callback(err)
    }
    var students = JSON.parse(data).students

    // findIndex 方法专门用来根据条件查找元素的下标
    var deleteId = students.findIndex(function (item) {
      return item.id === parseInt(id)
    })

    // 根据下标从数组中删除对应的学生对象
    students.splice(deleteId, 1)

    // 把对象数据转换为字符串
    var fileData = JSON.stringify({
      students: students
    })

    // 把字符串保存到文件中
    fs.writeFile(dbPath, fileData, function (err) {
      if (err) {
        // 错误就是把错误对象传递给它
        return callback(err)
      }
      // 成功就没错,所以错误对象是 null
      callback(null)
    })
  })
}


8. 回调函数
function fn(callback) {
  // var callback = function (data) { console.log(data) }

  setTimeout(function () {
    var data = 'hello'
    callback(data)
  }, 1000)
}

// 如果需要获取一个函数中异步操作的结果,则必须通过回调函数来获取
fn(function (data) {
  console.log(data)
})

node day4

1.mongoDB 数据库

[菜鸟教程](http://www.runoob.com/mongodb/mongodb-tutorial.htmll)

  1. 开启数据库服务
    #cmd
    # mongoDb 默认使用 monogd 命令所在根目录下的 /data/db 作为自己的数据库目录
    # 在第一次执行mongod命令之前需要 手动创建 /data/db
    mongod 
    #指定路径
    mongod --dbpath=F:\data\db
    
    
  2. 连接数据库
    mongo 
    
    
  3. 退出连接
    exit 
    
    
  4. 基本cmd命令
    • show dbs
      • 查看显示所有的数据库
    • db
      • 查看当前操作的数据库
    • use ’数据库名称‘
      • 切换到指定数据库(如果没有就新建)
    • show collections
      • 显示操作当前数据库的集合
    • db.集合名称.find()
      • 查看集合内容

2.在Node中操作MongoDB 数据

  • 使用第三方 mongoose 来操作MongoDB数据库

    • 第三方包 mongoose 基于 MongoDB官方的 mongodb
    • 文档:https://mongoosejs.com/docs/connections.html
    • 起步:
    1. 安装:

      npm i mongoose --save
      
      
    2. 基本使用 01:

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');
    }
  });
//}


基本使用02:设计文档结构 、约束集合内容
var mongoose = require('mongoose')

var Schema = mongoose.Schema

// 1. 连接数据库
// 指定连接的数据库不需要存在,当你插入第一条数据之后就会自动被创建出来
mongoose.connect('mongodb://localhost/itcast', { useMongoClient: true })

// 2. 设计文档结构(表结构)
// 字段名称就是表结构中的属性名称
// 约束的目的是为了保证数据的完整性,不要有脏数据
var userSchema = new Schema({
  username: {
    type: String,  //数据类型
    required: true // 必须有 ,不能为空
  },
  password: {
    type: String,
    required: true
  },
  email: {
    type: String,
      default'[email protected]' //默认值
  },
    gender:{
        type: Number,
        enum: [0,1]   //多选 只能选择0或1
    }
    
})

// 3. 将文档结构发布为模型
//    mongoose.model 方法就是用来将一个架构发布为 model
//    第一个参数:传入一个大写名词单数字符串用来表示你的数据库名称
//                 mongoose 会自动将大写名词的字符串生成 小写复数 的集合名称
//                 例如这里的 User 最终会变为 users 集合名称
//    第二个参数:架构 Schema
//   
//    返回值:模型构造函数
var User = mongoose.model('User', userSchema)



// 4. 当我们有了模型构造函数之后,就可以使用这个构造函数对 users 集合中的数据为为所欲为了(增删改查)

  var admin = new User({
   username: 'zs',
   password: '123456',
//   email: '[email protected]'
 })

 admin.save(function (err, ret) {
   if (err) {
     console.log('保存失败')
   } else {
     console.log('保存成功')
     console.log(ret)
   }
 })

查询所有

 
	 User.find(function (err, ret) {
	   if (err) {
		 console.log('查询失败')
	   } else {
		 console.log(ret)
	   }
	 })

根据条件查询单个数据

	User.findOne({
   username: 'zs'
 }, function (err, ret) {
   if (err) {
     console.log('查询失败')
   } else {
     console.log(ret)
   }
 })

根据id查询单个数据

User.findById([id],[callback])

根据条件删除所有:

 User.remove({
	 username: 'zs1' 
 },function (error,rte) {
	  if (error) {
	 		 console.log('删除失败')
	 } else {
	 		 console.log(rte)
	 }
 } )
 

根据条件删除一个:

User.findOneAndRemove(conditions,[options],[callback])

根据id删除一个:

User.findByIdAndRemove(id,[options],[callback])

根据条件更新所有:

User.update(conditions,doc,[options],[callback])

根据指定条件更新一个:

User.findOneAndUpdate(conditions,[updata],[options],[callback])

根据id更新一个:

 User.findByIdAndUpdate('5cb19423287071029435eede',{
	 password: '123789'
 },function (error,rte) {
	  if (error) {
	 		 console.log('更新失败')
	 } else {
	 		 console.log(rte)
	 }
 })

3.数据密码 MD5

MD5

​ 安装:

npm install blueimp-md5

​ 使用:

var md5 = require('blueimp-md5') 
// 对密码进行 md5 重复加密
body.password = md5(md5(body.password))

Node 操作MySQL

文档:https://www.npmjs.com/package/mysqli

安装:

npm i mysqli --save

实例化:

var mysql = require('mysql');

// 1. 创建连接
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'user' // 数据库名称
});

// 2. 连接数据库 打开冰箱门
connection.connect();

// 3. 执行数据操作 把大象放到冰箱
connection.query('SELECT * FROM `users`', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results);
});

// connection.query("任意mysql语句")', function (error, results, fields) {
//   if (error) throw error;
//   console.log('The solution is: ', results);
// });

// 4. 关闭连接 关闭冰箱门
connection.end();

回调地狱

nodejs个人学习笔记_第2张图片

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) {
     
      throw err
    }
    console.log(data)
    fs.readFile('./data/c.txt', 'utf8', function (err, data) {
      if (err) {
       
        throw err
      }
      console.log(data)
    })
  })
})


为了解决以上编程方式带来的问题(回调地狱嵌套),所以在EcmaScript6中新增了一个API:promise

promise基本语法

http://es6.ruanyifeng.com/?search=promise&x=15&y=5#docs/promise

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')
  })


图解

nodejs个人学习笔记_第3张图片

nodejs个人学习笔记_第4张图片

封装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)
  })


jquery使用promise
    
    // get('http://127.0.0.1:3000/users/4', function (userData) {
    //   get('http://127.0.0.1:3000/jobs', function (jobsData) {
    //     var htmlStr = template('tpl', {
    //       user: JSON.parse(userData),
    //       jobs: JSON.parse(jobsData)
    //     })
    //     console.log(htmlStr)
    //     document.querySelector('#user_form').innerHTML = htmlStr
    //   })
    // })

var data = {}
    $.get('http://127.0.0.1:3000/users/4')
     .then(function (user) {
        data.user = user
        return $.get('http://127.0.0.1:3000/jobs')
      })
      .then(function (jobs) {
        data.jobs = jobs
        var htmlStr = template('tpl', data)
        document.querySelector('#user_form').innerHTML = htmlStr
      })

json-server

安装

npm i json-server -g

使用

//再要执行的目录cmd
json-server --watch '文件名称'

day6

Node path 模块

nodejs个人学习笔记_第5张图片

node中的其他成员

nodejs个人学习笔记_第6张图片

Node中的 session (cookie)

npm文档

在 Express 这个框架中,默认不支持 Session 和 Cookie

但是我们可以使用第三方中间件:express-session 来解决

  1. 安装:
npm install express-session

  1. 配置
#引用
var express = requier('express')
var session = require('express-session')
#配置 在 app.use(router) 之前
app.use(session({
  // 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密
  // 目的是为了增加安全性,防止客户端恶意伪造
  secret: 'itcast',
  resave: false,
  saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙
}))

  1. 使用:
//    当把这个插件配置好之后,我们就可以通过 req.session 来发访问和设置 Session 成员了
//    添加 Session 数据:req.session.name = 'bar'
//    访问 Session 数据:req.session.name
	
	//清除 Session 数据: rep.session.name = null 
	//				   delete session.name
	


注意:默认session是存放在内存当中的,到生产环境时都会进行session持久化

PHP中的 cookie session

  1. session
$lifeTime = 24 * 3600
session_set_cookie_params($lifeTime)
session_start()
//设置
$_SESSION['值']
//销毁
unsettle($_SESSION['值'])


  1. cookie
//第三个参数不传是会话级别 浏览器关闭 cookie 自动清除
setcookie('name','value',time() + 1 * 24 * 60 * 60)

Node 综合案例

  1. 目录结构

    nodejs个人学习笔记_第7张图片

  2. 路由设计

    路径 方法 get参数 post参数 是否需要登录 备注
    / GET 渲染首页
    /register GET 渲染注册页面
    /register POST email、nickname,password 处理注册信息
    /login GET 渲染登录页

EcmaScript6

数组

  1. array.find()
  2. array.findIndex() 获取下标
var a = [1,2,3]
//当 `itme === 2` 成立时 find 会终止遍历,同时返回遍历项
a.find(function (itme) {return itme === 2})
 //输出 2


实现原代码

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
})

1. 目前关于数组循环的方法
  1. find()
  2. findIndex()
  3. forEach()
  4. every()
  5. some()
  6. includes()
  7. map()
  8. reduce()

3.数据密码 MD5

MD5

​ 安装:

npm install blueimp-md5

​ 使用:

var md5 = require('blueimp-md5') 
// 对密码进行 md5 重复加密
body.password = md5(md5(body.password))

Node 操作MySQL

文档:https://www.npmjs.com/package/mysqli

安装:

npm i mysqli --save

实例化:

var mysql = require('mysql');

// 1. 创建连接
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'user' // 数据库名称
});

// 2. 连接数据库 打开冰箱门
connection.connect();

// 3. 执行数据操作 把大象放到冰箱
connection.query('SELECT * FROM `users`', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results);
});

// connection.query("任意mysql语句")', function (error, results, fields) {
//   if (error) throw error;
//   console.log('The solution is: ', results);
// });

// 4. 关闭连接 关闭冰箱门
connection.end();

回调地狱

nodejs个人学习笔记_第8张图片

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) {
     
      throw err
    }
    console.log(data)
    fs.readFile('./data/c.txt', 'utf8', function (err, data) {
      if (err) {
       
        throw err
      }
      console.log(data)
    })
  })
})

为了解决以上编程方式带来的问题(回调地狱嵌套),所以在EcmaScript6中新增了一个API:promise

promise基本语法

http://es6.ruanyifeng.com/?search=promise&x=15&y=5#docs/promise

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')
  })

图解

nodejs个人学习笔记_第9张图片

nodejs个人学习笔记_第10张图片

封装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)
  })

jquery使用promise
    
    // get('http://127.0.0.1:3000/users/4', function (userData) {
    //   get('http://127.0.0.1:3000/jobs', function (jobsData) {
    //     var htmlStr = template('tpl', {
    //       user: JSON.parse(userData),
    //       jobs: JSON.parse(jobsData)
    //     })
    //     console.log(htmlStr)
    //     document.querySelector('#user_form').innerHTML = htmlStr
    //   })
    // })

var data = {}
    $.get('http://127.0.0.1:3000/users/4')
     .then(function (user) {
        data.user = user
        return $.get('http://127.0.0.1:3000/jobs')
      })
      .then(function (jobs) {
        data.jobs = jobs
        var htmlStr = template('tpl', data)
        document.querySelector('#user_form').innerHTML = htmlStr
      })

json-server

安装

npm i json-server -g

使用

//再要执行的目录cmd
json-server --watch '文件名称'

day6

Node path 模块

nodejs个人学习笔记_第11张图片

node中的其他成员

nodejs个人学习笔记_第12张图片

Node中的 session (cookie)

npm文档

在 Express 这个框架中,默认不支持 Session 和 Cookie

但是我们可以使用第三方中间件:express-session 来解决

  1. 安装:
npm install express-session
  1. 配置
#引用
var express = requier('express')
var session = require('express-session')
#配置 在 app.use(router) 之前
app.use(session({
  // 配置加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密
  // 目的是为了增加安全性,防止客户端恶意伪造
  secret: 'itcast',
  resave: false,
  saveUninitialized: false // 无论你是否使用 Session ,我都默认直接给你分配一把钥匙
}))
  1. 使用:
//    当把这个插件配置好之后,我们就可以通过 req.session 来发访问和设置 Session 成员了
//    添加 Session 数据:req.session.name = 'bar'
//    访问 Session 数据:req.session.name
	
	//清除 Session 数据: rep.session.name = null 
	//				   delete session.name
	

注意:默认session是存放在内存当中的,到生产环境时都会进行session持久化

PHP中的 cookie session

  1. session
$lifeTime = 24 * 3600
session_set_cookie_params($lifeTime)
session_start()
//设置
$_SESSION['值']
//销毁
unsettle($_SESSION['值'])

  1. cookie
//第三个参数不传是会话级别 浏览器关闭 cookie 自动清除
setcookie('name','value',time() + 1 * 24 * 60 * 60)

Node 综合案例

  1. 目录结构

    nodejs个人学习笔记_第13张图片

  2. 路由设计

    路径 方法 get参数 post参数 是否需要登录 备注
    / GET 渲染首页
    /register GET 渲染注册页面
    /register POST email、nickname,password 处理注册信息
    /login GET 渲染登录页

EcmaScript6

数组

  1. array.find()
  2. array.findIndex() 获取下标
var a = [1,2,3]
//当 `itme === 2` 成立时 find 会终止遍历,同时返回遍历项
a.find(function (itme) {return itme === 2})
 //输出 2

实现原代码

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
})
1. 目前关于数组循环的方法
  1. find()
  2. findIndex()
  3. forEach()
  4. every()
  5. some()
  6. includes()
  7. map()
  8. reduce()

server

var express = require('express'); //express框架模块
var path = require('path'); //系统路径模块
var fs = require('fs'); //文件模块
var bodyParser = require('body-parser'); //对post请求的请求体进行解析模块
var app = express();
app.use(bodyParser.urlencoded({ extended: false })); //bodyParser.urlencoded 用来解析request中body的 urlencoded字符,只支持utf-8的编码的字符,也支持自动的解析gzip和 zlib。返回的对象是一个键值对,当extended为false的时候,键值对中的值就为'String'或'Array'形式,为true的时候,则可为任何数据类型。
// var hostName = '192.167.0.0.1'; //ip
var hostName = '192.168.43.35'; //ip
var port = 88; //端口
app.engine('html',require('express-art-template'))
//设置允许跨域请求
// app.all('*', function(req, res, next) {
//     res.header('Access-Control-Allow-Origin', '*'); //访问控制允许来源:所有
//     res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); //访问控制允许报头 X-Requested-With: xhr请求
//     res.header('Access-Control-Allow-Metheds', 'PUT, POST, GET, DELETE, OPTIONS'); //访问控制允许方法
//     res.header('X-Powered-By', 'nodejs'); //自定义头信息,表示服务端用nodejs
//     res.header('Content-Type', 'application/json;charset=utf-8');
//     next();
// });
app.use('/public/', express.static('./public/'))
// app.use('/api/', express.static('./api/'))


app.get('/',function (request,response) {
    response.send('QAQ')
})
app.get('/note.html',function (request,response) {
    response.render('note.html', {
        title: 'hell note'
    })
})
//创建get接口
app.get('/api/mbApi.json', function(req, res) {

    //console.log(req.body); //获取请求参数

    var file = path.join(__dirname, 'api/mbApi.json'); //文件路径,__dirname为当前运行js文件的目录
    //var file = 'f:\\nodejs\\data\\test.json'; //也可以用这种方式指定路径

    //读取json文件
    fs.readFile(file, 'utf-8', function(err, data) {
        if (err) {
            res.send('文件读取失败');
        } else {
			var strData = JSON.stringify(data)
			var newData = JSON.parse(strData)
            res.send(newData);
        }
    });
});

app.listen(port, hostName, function() {

    console.log(`服务器运行在http://${hostName}:${port}`);

});

你可能感兴趣的:(nodejs,笔记)