当前位置: 首页 > 后端技术 > Node.js

koaserver入门

时间:2023-04-03 14:17:17 Node.js

介绍koa是一个比express更小、更健壮、表现力更强的web框架。Koa通过组合不同的生成器来避免繁琐的回调函数调用。Koa的核心库没有绑定任何中间件,只提供了一个轻量级优雅的函数库,让编写web应用变得简单。koa模块可以在项目目录路径下运行命令npminstall--save-devkoa安装到本地。安装完成后写一个helloworld验证是否生效。你好世界你好世界代码非常简单。constkoa=require('koa');constapp=koa();app.use(function*(){this.body='helloworld';});app.listen(3000);以上8行代码就是实现了koa的helloworld。第4行调用的app.use()传入了一个generator方法,这是koa中间件的基本实现。koa应用的实现是通过中间件一个一个实现的。每个中间件都是一个生成器方法,一个中间件的逻辑通过yield语句级联。例如:constkoa=require('koa');constapp=koa();//x-response-timeapp.use(function*(next){console.log('line1');conststart=newDate;yieldnext;console.log('line5');constms=newDate-start;this.set('X-Response-Time',${ms}ms);});//logtimeapp.use(function*(next){console.log('line2');conststart=newDate;yieldnext;console.log('line4');constms=newDate-start;console.info('%s%s:%sms',this.method,this.url,ms);});//responseapp.use(function*(next){console.log('line3');this.body='helloworld';});app.listen(3000);运行上面的代码后,当有请求被触发时,consolelog会打印如下日志(请忽略上面代码中的info日志):line1line2line3line4line5可以看出koa中间件的运行是按收益率分为两部分运行。运行时序如下:koa框架本身的功能很简单,koa应用的功能都是通过中间件来实现的,下面介绍几个常用的koa中间件。koa-statickoa-static是一个管理静态文件请求的中间件。比如当你想请求html、JS、图片等静态文件时,可以使用koa-static来实现。比如项目根目录下的static目录用来存放静态文件,那么下面的代码就可以实现该目录下的静态文件请求constpath=require('path');conststaticServer=require('koa-静态');app.use(staticServer(path.join(__dirname,'static')));koa-routerkoa-router是一个路由中间件,用法如下:constrouter=require('koa-router')();//监听url请求router.get('/list',function*(){//...});router.post('/user/register',function*(){//...});koa-safe-jsonpJSONP格式返回的中间件,用法:constjsonp=require('koa-safe-jsonp');constrouter=require('koa-router');constkoa=require('koa');constapp=koa();jsonp(app);router.get('./list',function*(){constlist=[];this.json=list;});koa-session会话管理中间件,用法:constsession=require('koa-session');app.use(session(app));router.post('./user/login',function*(){this.session.user=user;});koa-onerrorkoa-onerror用于格式化异常页面输出。用法:constonerror=require('koa-onerror');constkoa=require('koa');constapp=koa();错误(应用程序);中间件实现上面列出的常用中间件是非常常用的中间件,但是在业务开发过程中,我们会根据业务场景实现一些特殊的中间件,那么如何开发一个中间件呢?下面说说koa的中间件是如何实现的。比如我们要实现一个统计请求响应的功能,我们可以开发一个统计请求响应时间的中间件来使用。基本上,从上面的例子可以看出中间件是通过app.use()注册的,app.use()方法的参数是一个generator方法。所以koa中间件需要返回一个generator方法,所以实现代码如下://middleware/timer.jsmodule.exports=function(){returnfunction*(next){constpath=this.path;const开始=新日期;yieldnext;constend=newDate;console.log(`${path}响应时间:${end-start}ms`);}};//server.jsconsttimer=require('./middleware/timer.js');app.use(timer());以上代码实现了统计请求响应时间的功能。功能非常简单。middleware/timer.js直接返回一个generator方法,分别统计请求开始时间和结束时间,并打印时间差。我们可以把中间件设计的复杂一点,比如我们可以控制过滤掉一些不打印的请求,打印的格式也可以控制。这时候我们就需要传入一些参数来控制中间件的功能。代码如下://middleware/timer.jsmodule.exports=functiontimer(options){returnfunction*timer(){letstart=newDate;constpath=this.path;constmethod=this.request.method;if(method!==options.filter.method)start=0;yieldnext;constend=newDate;if(start!==0&&end-start>options.filter.min){console.log(options.format.replace(/:url/g,path).replace(/:time/g,`${end-start}ms`));}}};//server.jsconsttimer=require('./middleware/timer.js');//GET请求超过100ms时,打印日志,日志格式:urltimeapp.use(timer({format:':url:时间”过滤器:{min:100method:'GET'}}));koa源码理解第一篇介绍中提到,koa的核心库非常简单,没有绑定任何中间件。那么,最后说一下koa的源码吧。koa.js的源码可以在https://github.com/koajs/koa获取。koa.js的源码有4个文件,分别是lib/application.js、lib/context.js、lib/request.js、lib/response.js。从名字可以看出,context.js、request.js、response.js分别是context对象、request对象、response对象,application.js是koa.js的核心代码。在上面的示例中,使用了两个接口,use和listen。先介绍一下这两个方法,下面是这两个方法在application.js中的源码://...app.listen=function(){debug('listen');varserver=http.createServer(this.callback());returnserver.listen.apply(server,arguments);};//...app.use=function(fn){if(!this.experimental){//es7异步函数是不允许的,//所以我们有确保`fn`是一个生成器函数_name||fn.name||'-');这个.middleware.push(fn);returnthis;};//...可见use的作用是将传入的中间件generator方法放在this.middleware中。listen接口的作用其实就是启动一个server,将请求处理设置为this.callback()的返回方法。然后我们看看this.callback是怎么写的://...app.callback=function(){if(this.experimental){console.error('ExperimentalES7AsyncFunctionsupportisdeprecated.请查看Koav2作为中间件签名已更改。')}varfn=this.experimental?compose_es7(this.middleware):co.wrap(compose(this.middleware));varself=this;if(!this.listeners('error').length)this.on('error',this.onerror);returnfunction(req,res){res.statusCode=404;varctx=self.createContext(req,res);onFinished(res,ctx.onerror);fn.call(ctx).then(function(){响应.call(ctx);}).catch(ctx.onerror);}};//...核心代码就是这两句://...co.wrap(compose(this.middleware));//...returnfunction(req,res){//...fn.call(ctx).then(function(){respond.call(ctx);}).catch(ctx.onerror);}//...compose(this.middleware)的作用是将传入的中间件数组组合成一个层层调用的生成器函数。co.wrap()方法的作用是将生成器编号转化为自执行函数。最后的fn.call(ctx)开始单步执行中间件。