koa2全了解

1nodejs必须>7.6才完全支持koa2
koa2与express相比就是能避免异步嵌套

//0必须先安装完nodejs后才能
//1创建目录夹

//2项目初始化
npm init

//3项目安装koa
npm install --save koa

//4第一个helloworld
const koa = require("koa");

let app = new koa();

app.use(async (ctx)=>{
    ctx.body = "你好";
});

app.listen(3000);

async用于声明一个function是异步的
await是等待异步方法执行完成,并且必须用在异步方法里面才不报错
nodejs里面所有的方法都是异步,所以await可以直接用在方法内调用方法
区别:
promise代表一个对象是异步的(对应then),async代表一个方法是异步的(对应await)
//await阻塞的功能,可以把异步改成同步

async function getData() {
    return "这是一个异步方法";
}
console.log(getData());//Promise { '这是一个异步方法' }


//await是等待异步方法执行完成,并且必须用在异步方法里面才不报错
async function getData() {
    return "这是一个数据";
}
async function getData2() {
   let p = await getData();
   console.log(p);
}
getData2();


//await阻塞功能
async function getData() {
    console.log(2);
    return "这是一个数据";
}
async function getData2() {
    console.log(1);
   let p = await getData();
   console.log(p);
   console.log(3);
}
getData2();//1,2,3 await阻塞功能

//await也可获取Promise的异步返回结果
function getData() {
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            let name = "张三";
            resolve(name);
        },1000)
    });
}
async function test(){
    var data = await getData();
    console.log(data);
}
test();
//安装koa-router,koa的路由器
npm install koa-router --save

//1引入模块,类的命名一般首字母大写
 const Koa = require("koa");
// const Router = require('koa-router');
//2实例化对象
 let app = new Koa();
// let router = new Router();

//一步引入并实例化路由
let router = require('koa-router')();


//3ctx表示上下文content,包含了request和response等信息
router.get('/',async (ctx)=>{
    ctx.body="首页"; //返回数据 相当于原生里面的res.writeHead() res.end();
}).get('/news',async (ctx)=>{
    ctx.body="新闻页面";
})

//4配置路由,必须加
app
    .use(router.routes()) //配置路由
    .use(router.allowedMethods()); //建议配置:作用:可以根据ctx.status设置response响应头

//5设置监听端口
app.listen(3000);
//1引入模块,类的命名一般首字母大写
 const Koa = require("koa");
// const Router = require('koa-router');
//2实例化对象
 let app = new Koa();
// let router = new Router();

//一步引入并实例化路由
let router = require('koa-router')();


//3ctx表示上下文content,包含了request和response等信息
router.get('/',async (ctx)=>{
    ctx.body="首页"; //返回数据 相当于原生里面的res.writeHead() res.end();
}).get('/news',async (ctx)=>{
    ctx.body="新闻页面";
}).get('/newscontent/:aid',async (ctx)=>{
	//动态路由也可以传多个值,但必须全匹配才正常返回
    //动态路由http://localhost:3000/newscontent/xxx   console.log(ctx.params);获得{ aid: 'xxx' }

    //http://localhost:3000/newscontent?adi=123
    // 在 koa2 中 GET 传值通过 request 接收,但是接收的方法有两种:query 和 querystring。
    // query:返回的是格式化好的参数对象。
    // querystring:返回的是请求字符串。
    // console.log(ctx.query); //{ adi: '123' }获取的是对象,常用
    // console.log(ctx.querystring); //adi=123 获取的是字符串
    // console.log(ctx.request); //获取全部信息

    console.log(ctx.params);

    ctx.body="新闻详情页面";
})

//4配置路由,必须加
app
    .use(router.routes()) //配置路由
    .use(router.allowedMethods()); //建议配置:作用:可以根据ctx.status设置response响应头

//5设置监听端口
app.listen(3000);

koa的4种中间件:
应用级中间件
路由级中间件
错误处理中间件
第三方中间件
koa2全了解_第1张图片

//1引入模块,类的命名一般首字母大写
 const Koa = require("koa");
//2实例化对象
 let app = new Koa();
//一步引入并实例化路由
 let router = require('koa-router')();



//3ctx表示上下文content,包含了request和response等信息
router.get('/',async (ctx)=>{
    ctx.body="首页"; //返回数据 相当于原生里面的res.writeHead() res.end();
}).get('/news',async (ctx,next)=>{
    //路由级中间件next
    ctx.body="新闻页面";
    await next();
}).get('/newscontent/:aid',async (ctx)=>{
    ctx.body="新闻详情页面";
})

router.get('/news',async (ctx)=>{
    console.log("新闻页面");
})

//匹配所有路由,如果不写next,这个路由被匹配到了,就不会继续向下匹配(应用级中间件),app.use最先执行
app.use(async (ctx,next)=>{
    console.log(new Date());
    console.log(ctx);
    await next();

    //错误处理中间件
    if(ctx.status==404){
        ctx.status = 404;
        ctx.body = "404页面";
    } else {
      console.log(ctx.url);
    }
});

//4配置路由,必须加
app
    .use(router.routes()) //配置路由
    .use(router.allowedMethods()); //建议配置:作用:可以根据ctx.status设置response响应头

//5设置监听端口
app.listen(3000);

//5 ejs模板

//安装模板引擎
npm install koa-views --save
//安装ejs
npm install ejs --save
//配置全局变量,(放在一个中间件里),注意➕await next();
ctx.state.info="张三"

//案例
const Koa = require("koa");
const router = require('koa-router')();
const views = require('koa-views');

let app = new Koa();

app.use(views('views',{
    extension:'ejs'
}));

router.get('/',async (ctx)=>{
    await ctx.render('index');
})
router.post('/add',async (ctx)=>{
    console.log(ctx);
})

app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);

6获取post请求的数据中间间 koa-bodyparser

//安装
npm install --save koa-bodyparser
//引入
const bodyParser = require('koa-bodyparser');
//使用
app.use(bodyParser());
//中间件中获取post数据
ctx.request.body

7静态资源中间件

//安装
npm install koa-static --save
//引入
const static = require('koa-static');
//使用(可配置多个)
app.use(static('static'));
或app.use(static(__dirname+'static'));

//ejs文件引入也只需写static文件夹后面的目录即可

8koa的cookie,(cookie无需安装即可使用)

1 HTTP 是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页 面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。

2cookie 是存储于访问者的计算机中的变量。可以让我们用同一个浏览器访问同一个域名的时候共享数据。

//koa设置cookies
ctx.cookies.set(name, value, [options])
//koa获取cookies
ctx.cookies.get('name');
//正常使用
ctx.cookies.set('userInfo',userInfo,{
        maxAge:60*1000*60,
        httpOnly:false  //只服务器端和客户端(js)都可以访问
    });
    
//需要转string类型存储,get时再转json类型
router.get('/showinfo',async (ctx)=>{
    // let userInfo = ctx.cookies.get('userInfo');
    // ctx.body = userInfo;
    ctx.body = JSON.parse(ctx.cookies.get('userInfo')).username;
})
router.post('/add',async (ctx)=>{
    let userInfo = JSON.stringify(ctx.request.body);
    ctx.cookies.set('userInfo',userInfo,{
        maxAge:60*1000*60
    });
    ctx.body=userInfo;
})
//koa的cookie存储中文bug-转base64进行存储,取出再转中文
let name = new Buffer('刘晓飞').toString('base64');// 转换成 base64
ctx.cookies.set('name',name);
//取
console.log(new Buffer(ctx.cookies.get('name'), 'base64').toString());

options可能的值
koa2全了解_第2张图片

9session

//安装
npm install koa-session --save
//引入
const sesstion = require('koa-session');
//配置
app.keys = ['some secret hurr'];//cookie签名,不管
const CONFIG = {
    key: 'koa:sess', //cookie的key,不管
    maxAge: 86400000, //cookie过期时间,毫秒 [需要修改]
    autoCommit: true,
    overwrite: true, //没效果,不管
    httpOnly: true, //true表示只有服务器端可获取cookie
    signed: true, //签名,默认
    rolling: false, //在每次请求时强行设置cookie,这将重置cookie过期时间(默认:false)
    renew: true, //快过期是否重新设置cookie,一般是true  [需要修改]
};
app.use(session(CONFIG, app));

//使用
设置值 ctx.session.username = "张三";
获取值 ctx.session.username

Cookie 和 Session 区别 1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗 考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 考虑到减轻服务器性能方面,应当使用 COOKIE。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。

10The yield keyword is used to pause and resume a generator function.

Generator函数的最大用处就是用来生成一个遍历器。

不过它是一个函数,所以和普通的函数有点区别,因此在声明函数的时候,要在function和函数名之间加一个*号:
function *foo() {}

yield也必须在Generator函数中才有意义

// yield这个关键字是用来暂停和恢复一个遍历器函数(的运行)的。
而yield告诉程序当前的状态值,而且你运行到这里给我暂停一下。

就用上面的代码来说好了。Generator函数的特点就是“它是一个遍历器”,你不让它动,它绝对不会动。

函数只能返回一次,所以必须返回一个Array。但是,如果换成generator,就可以一次返回一个数,不断返回多次。
因为generator可以在执行过程中多次返回,所以它看上去就像一个可以记住执行状态的函数,利用这一点,写一个generator就可以实现需要用面向对象才能实现的功能。

generator还有另一个巨大的好处,就是把异步回调代码变成“同步”代码。
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143450083887673122b45a4414333ac366c3c935125e7000

var foo = function *() {
		  var x = 1;
		  var y =  yield (x + 1);
		  var z = yield (x + y);
		  return z;
		}()
		var a = foo.next(); // 第一次执行next()不可以传参,a.value你应该知道,就2(x = 1, x + 1 = 2)。
		console.log(a); //2
		var b = foo.next(3); //第二次执行foo.next(3)的时候,yield x + 1这一大坨就是3,所以y = 3!“xx老谋”。所以,b.value的结果就是4 (x = 1,y = 3, x + y = 4).
		console.log(b); //4
		var c = foo.next(4);
		console.log(c); //4

总结一下
写了这么多,总结一下yield,实际上:

只能在Generator函数内部使用
运行.next(),遇到一个yield命令,就暂停
.next()的返回值表示一个状态{value,done}
再运行.next(),从之前遇到的那个yield [表达式]处(后)继续恢复运行
当.next()传参的时候,yield [表达式]整个被替换为传入的参数。

最后,说一下for...of是怎么运行的。

function *foo() {
  yield 1;
  yield 2;
  yield 3;
  return;
}
for(let v of foo()) {
  console.log(v);
}
for...of在遍历foo()返回的结果时,每遇到一个yield,就把yield后面表达式的结果作为of前面的v的值进行赋值(next()返回值的value字段)。

你可能感兴趣的:(前端,koa)