介绍
koa,是基于Node.js 平台的下一代的web开发框架。
是由Express原班人马打造,致力于成为一个更小的,更加富有表现力的,web框架。
使用koa编写web应用,可以免除重复的回调函数嵌套,并极大的提高错误处理的效率,
koa框架不仅仅在内核方法中可以绑定任何中间件,它仅仅提供了一个轻量级,优雅的函数库,思路和express相差不少。
koa框架的安装
安装koa
安装koa框架和安装之前的模块一样。
使用如下命令安装
代码语言:txt复制npm install --save koa
使用save参数,表明将会自动修改package.json 文件。自动添加依赖项
hello world
输入如下的代码,运行hello world
代码语言:txt复制const koa = require("koa");
const app = new koa();
// 配置中间件
app.use(async (ctx) => {
ctx.body = "hello world";
})
// 监听端口
app.listen(3000);
运行文件
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
输出结果如下
异步的处理
由于js是单线程的,所以,使用回调函数处理异步等问题。
回调函数处理
代码语言:txt复制const koa = require("koa");
const app = new koa();
function getData(callback){
setTimeout(function () {
var name = "ming";
callback(name);
}, 1000)
}
// 从外部获取异步方法里的数据
getData(function (data) {
console.log(data)
})
// 监听端口
app.listen(3000);
输出结果
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
ming
使用promise处理异步
代码语言:txt复制const koa = require("koa");
const app = new koa();
// promise 处理异步
// resolve 成功的回调函数
// reject 失败的回调函数
var p = new Promise(function (resolve, reject) {
setTimeout(function () {
var name = "张三";
}, 1000)
})
// 获取异步的结果
p.then((data) => {
console.log(data);
})
// 监听端口
app.listen(3000);
运行结果如下
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
ming
关于async await promise
其中async是异步的缩写,await被认为是async wait的缩写,所以,async用于申明一个函数为异步的,await用于等待一个异步方法执行完成。
简单理解
async 让方法变成异步
await 等待异步方法执行完成。
async
实际例子
这里使用实际的例子,更好理解。
同步函数
代码语言:txt复制function getData(){
return "ming";
}
console,log(getData())
输出结果
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
ming
async 可以让该方法变成异步
代码语言:txt复制const koa = require("koa");
const app = new koa();
// promise 处理异步
// resolve 成功的回调函数
// reject 失败的回调函数
async function getData(){
return "这是一个数据";
}
console.log(getData());
// 监听端口
app.listen(3000);
输出结果如下所示
其中promise为一个异步的数据
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
Promise { '这是一个数据' }
获取该数据
代码语言:txt复制const koa = require("koa");
const app = new koa();
// promise 处理异步
// resolve 成功的回调函数
// reject 失败的回调函数
async function getData(){
return "这是一个数据";
}
var p = getData();
p.then((data) => {
console.log(data);
})
// 监听端口
app.listen(3000);
输出结果如图所示
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
这是一个数据
await
使用await方法获取到异步的信息
代码语言:txt复制const koa = require("koa");
const app = new koa();
// promise 处理异步
// resolve 成功的回调函数
// reject 失败的回调函数
async function getData(){
return "这是一个数据";
}
async function test(){
// 此时运行的为,发现该函数是一个异步函数,遇到了await进入等待状态,等待getData执行完毕,再往下执行
var d = await getData();
console.log(d)
}
test()
// 监听端口
app.listen(3000);
运行结果
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
这是一个数据
koa 路由
路由是根据不同的url地址,加载不同页面实现不同的功能。
安装路由
代码语言:txt复制 npm install --save koa-router
使用路由
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", (ctx, next) => {
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
运行结果如下所示
其中可以添加async作为异步方法来调用
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
获取链接的参数值
通过router获取路由的参数值
链接为
获取格式化好的
代码语言:txt复制http://localhost:3000/?ming=3
代码为
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.query)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
访问的结果是
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
[Object: null prototype] { ming: '3' }
获取未格式化好的
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
ming=3
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
router.get("/", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.querystring)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
设置动态路由
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 配置动态路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.params)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
访问的链接为
代码语言:txt复制http://localhost:3000/ming
输出的内容
代码语言:txt复制PS C:UsersAdministratorIdeaProjectsuntitled3> node ./ming.js
{ id: 'ming' }
koa 中间件
这里配置koa的中间件
中间件就是匹配路由完成做的一系列的操作,把它称之为中间件。
中间件的功能主要有:
- 执行任何代码
- 修改请求和响应的对象
- 终结请求,响应循环
- 调用堆栈中的下一个中间件。
需求: 打印出中间件相关内容
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中间件
app.use(async (ctx) => {
ctx.body = "这是一个中间件";
})
// 配置动态路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.params)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
运行结果
此时访问任何页面出现的都是这个内容,
持续匹配
因为访问的时候,没有加上next,此时造成的无法进入到匹配路由的阶段。
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中间件
app.use(async (ctx, next) => {
ctx.body = "这是一个中间件";
// 进入路由匹配
next();
})
// 配置动态路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.params)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
由于js是单线程的,此时需要添加await,进行访问。
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中间件
app.use(async (ctx, next) => {
ctx.body = "这是一个中间件";
// 进入路由匹配
await next();
})
// 配置动态路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.params)
ctx.body = "ming";
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
路由持续匹配
路由由于没有await next,造成路由匹配到以后就不再匹配,所以添加next,能把两个相同的路由按照顺序,匹配完成。
代码语言:txt复制const koa = require("koa");
const app = new koa();
const router = require("koa-router")();
// 中间件
app.use(async (ctx, next) => {
ctx.body = "这是一个中间件";
// 进入路由匹配
await next();
})
// 配置动态路由
router.get("/:id", async (ctx, next) => {
// query 返回的是格式化好的参数对象
// querystring 返回的是请求的字符串
console.log(ctx.params)
ctx.body = "ming";
await next();
})
router.get("/:id", async (ctx, next) => {
// 此时匹配到这点
await next();
})
// 启动路由
app.use(router.routes());
// 设置响应头
app.use(router.allowedMethods());
// 监听端口
app.listen(3000);
中间件的执行顺序
一般是洋葱模型,作为中间件的执行顺序。
错误处理中间件
代码语言:txt复制// 中间件
app.use(async (ctx, next) => {
console.log("这是一个中间件");
// 进入洋葱
next()
// 出洋葱
if(ctx.status = 404){
ctx.status = 404;
ctx.body = "这是一个 404 页面";
}
})
第三方中间件
例如进行静态文件托管的时候,使用的是第三方中间件
代码语言:txt复制const static = require('koa-static');
const staticPath = './static';
app.use(static(
path.join(__dirname, staticPath);
))
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
这样就完成了静态文件托管