一 koa-generateor
1.全局安装generator
npm install -g koa-generator
2.新建koa2项目
// 使用es引擎创建项目
koa2 -e koa2-learn
3.启动项目
npm start,
// 可以自启动
npm run dev
二 async(异步)和await(等待)语法
1.异步的概念
同步:任务按排列顺序执行。
异步:其实就是延迟处理,在和html交互的过程中,会需要一些IO操作(典型的就是ajax请求,脚本文件加载),如果这些操作是同步的,用户的体验就是页面失去了响应,异步是通过异步函数实现的,如setTimeout()。实现方式从最开始的回调函数,到promise,再到ES6中的async/await。
2.Promise
- promise的状态 promise的三种状态:pending(异步操作未完成),resolved(异步操作已完成),rejected(异步操作失败)。promise的2种结果(resolved,rejected),异步操作成功promise传回一个值,状态为resolved,异步操作失败promise对象抛出一个错误,状态变为rejected。
- promise的用途:用于异步计算;将异步操作队列话,按照期望的顺序执行,返回符合预期的结果;可以在对象之间传递和操作promise,帮助我们处理队列;它就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
- promise的2个特点:对象的状态不受外界的影响,只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态;一旦状态改变就不会再变,任何时候都可以得到这个结果。
- promise的缺点:一旦新建一个promise就会立即执行,无法中途取消;如果不设置回调函数,promise的错误不会反应到外部;出于pending状态时,无法得知当前进行到哪一步。
new promise(
// 执行器
function (resolve, reject) { // 一段耗时很长的异步操作
resolve(); // 数据处理完成
reject(); //数据处理出错
}
).then( function A() { //成功,下一步
}, function B(){ //失败,下一步
})
3.async/await
await后面接一个会return new promise的函数并执行它
await只能放在async函数里
例:使用async和await获取成功的结果
function action1(){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
setTimeout(()=>{
resolve(sino)
},3000)
})
}
async function test(){
let n =await action1()
console.log(n)
}
test()
上面这段代码async中使await action1()先执行,等到三秒后执行完再把得到的结果赋值给左边的n,也就是说test函数需要三秒钟才执行完成,所以test函数是异步的,因此前面必须写async
例:使用async和await获取失败的结果
function action2(猜测){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
if(sino > 3){
if(猜测 === '大'){
resolve(sino)
}else{
reject(sino)
}
}else{
if(猜测 === '大'){
reject(sino)
}else{
resolve(sino)
}
}
setTimeout(()=>{
resolve(sino)
},300)
})
}
async function test(){
try{
//把await及获取它的值的操作放在try里
let n =await action2('大')
console.log('赢了' + n)
}catch(error){
//失败的操作放在catch里
console.log('输了' + error)
}
}
test()
把await和成功后的操作放到try里,失败的放在catch。
例:使用promise拿到所有的promise都结束后的结果
Promise.all([action2('大'),action2('大')]).then((x)=>{
console.log(x)
},(y)=>{
console.log(y)
})
promise.all里面跟一个数组,数组的每一项调用一个返回promise的函数,then的第一个参数是所有的promise都成功后返回sino值的一个数组;第二个参数拿到的是第一个失败的sino值。
例:使用await拿到所有的promise都结束后的结果
async function test(){
try{
let n = await promise.all([action2('大'),action2('大')])
console.log(n)
}catch(error){
console.log(error)
}
}
test()
async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)
例:如果asycn里的代码都是同步的,那么这个函数被调用就会同步执行
async function fn(){
console.log('a')
}
fn()
console.log('b')
//a
//b
三 koa2中间件
示例:
app.use(async (ctx,next) =>{
console.log(1);
await next() //继续往下执行下一个中间件,next非常重要,一定要写,不然后面的中间件无法执行
console.log(2);
});
app.use(async (ctx,next) =>{
console.log(3);
const axios = require('axios');
const res = await axios.get('https://www.baidu.com/');
console.log(4);
});
想要保证洋葱模型的话就要使用async/await(必须在方法前面加上async,在next()前面加上await),下面的代码的执行顺序就变成了标准的洋葱模型,1,3,4,2
四 koa2路由
查看相关api地址:github.com/ZijianHe/ko…
示例:
const router = require('koa-router')()
// render:渲染页面的
router.get('/', async (ctx, next) => {
await ctx.render('index', {
title: 'Hello Koa 2!'
})
})
// ctx.body:用来写接口的
router.get('/string', async (ctx, next) => {
ctx.body = 'koa2 string'
})
router.get('/json', async (ctx, next) => {
ctx.body = {
title: 'koa2 json'
}
})
router.get('/testAsync', async (ctx) => {
console.log('start', new Date().getTime())
const a = await new Promise((resolve, reject) => {
setTimeout(function () {
console.log('async a', new Date().getTime())
resolve('3333')
}, 1000)
})
ctx.body = {
a
}
})
module.exports = router //最后不要忘记导出,导出后在app.js里面使用app.use(XX)
给所有路径加前缀,相当于模块化:
router.prefix('/users'); // 路由模块化;
// 访问这个页面 http://localhost:3000/users/bar
router.get('/bar', function (ctx, next) {
ctx.body = 'this is a users/bar response'
})
五 cookie和session
查看相关api地址:koa.bootcss.com/#introducti…
//cookies用法
ctx.cookies.set('name', 'tobi', { signed: true });
session:服务端用session来保存用户状态和标识。 session和cookie的关系是:服务端把session设置到cookie里传递给客户端,客户端下次访问服务器其他接口时又会通过cookie把这个session信息传给服务端,服务端以此来进行判断用户权限。