创建koa2工程

首先,我们创建一个目录hello-koa并作为工程目录用VS Code打开。然后,我们创建app.js,输入以下代码:

// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa=require('koa2'); // 创建一个Koa对象表示web app本身:
const app = new Koa(); // 对于任何请求,app将调用该异步函数处理请求:
app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
}); // 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
//可以在http://127.0.0.1:3000访问

对于每一个http请求,koa将调用我们传入的异步函数来处理:

async (ctx, next) => {
await next();
// 设置response的Content-Type:
ctx.response.type = 'text/html';
// 设置response的内容:
ctx.response.body = '<h1>Hello, koa2!</h1>';
}

其中,参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response,next是koa传入的将要处理的下一个异步函数。

上面的异步函数中,我们首先用await next();处理下一个异步函数,然后,设置response的Content-Type和内容。

async标记的函数称为异步函数,在异步函数中,可以用await调用另一个异步函数,这两个关键字将在ES7中引入。

廖老师官网上还探讨了koa2这个包怎么装,但是现在koa2已经嵌入了node中,不用另外npm安装,这里就忽略了,直接用require在项目中引入使用即可。

koa middleware(koa的核心代码   中间件)

让我们再仔细看看koa的执行逻辑。核心代码是:

app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
});

每收到一个http请求,koa就会调用通过app.use()注册的async函数,并传入ctxnext参数。

我们可以对ctx操作,并设置返回内容。但是为什么要调用await next()

原因是koa把很多async函数组成一个处理链,每个async函数都可以做一些自己的事情,然后用await next()来调用下一个async函数。我们把每个async函数称为middleware,这些middleware可以组合起来,完成很多有用的功能。

例如,可以用以下3个middleware组成处理链,依次打印日志,记录处理时间,输出HTML:

app.use(async (ctx, next) => {
console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
await next(); // 调用下一个middleware
}); app.use(async (ctx, next) => {
const start = new Date().getTime(); // 当前时间
await next(); // 调用下一个middleware
const ms = new Date().getTime() - start; // 耗费时间
console.log(`Time: ${ms}ms`); // 打印耗费时间
}); app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
});

middleware的顺序很重要,也就是调用app.use()的顺序决定了middleware的顺序。

此外,如果一个middleware没有调用await next(),会怎么办?答案是后续的middleware将不再执行了。这种情况也很常见,例如,一个检测用户权限的middleware可以决定是否继续处理请求,还是直接返回403错误:

app.use(async (ctx, next) => {
if (await checkUserPermission(ctx)) {
await next();
} else {
ctx.response.status = 403;
}
});

理解了middleware,我们就已经会用koa了!

最后注意ctx对象有一些简写的方法,例如ctx.url相当于ctx.request.urlctx.type相当于ctx.response.type

node中的koa2的更多相关文章

  1. node中的Stream-Readable和Writeable解读

    在node中,只要涉及到文件IO的场景一般都会涉及到一个类-Stream.Stream是对IO设备的抽象表示,其在JAVA中也有涉及,主要体现在四个类-InputStream.Reader.Outpu ...

  2. 深入理解jQuery、Angular、node中的Promise

    最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...

  3. Node中的定时器详解

    在大多数的业务中,我们都会有一些需求,例如几秒钟实现网页的跳转,几分钟对于后台数据进行清理,node与javascript都具有将代码延迟一段时间的能力.在node中可以使用三种方式实现定时功能:超时 ...

  4. node中的可读流和可写流

    javascript的一个不足之处是不能处理二进制数据,于是node中引入了Buffer类型.这个类型以一个字节(即8位)为单位,给数据分配存储空间.它的使用类似于Array,但是与Array又有不同 ...

  5. node中的Readable - flowing/non-flowing mode

    大家都知道在node中Readable Stream有两种模式: flowing mode和non-flowing mode. 对于flowing mode的Readable Stream, 我们是没 ...

  6. 清理8组nodes中表的历史数据,平均每个node中的表有1.5亿条记录,需要根据date_created字段清理8000W数据记录,这个字段没有索引。

    清理8组nodes中表的历史数据,平均每个node中的表有1.5亿条记录,需要根据date_created字段清理8000W数据记录,这个字段没有索引. 环境介绍  线上磁盘空间不足,truncate ...

  7. 重回博客 谈一谈Node中的异步和单线程

    重回博客,这个帐号之前注册后就只发了一篇博客.听朋友建议,决定一周两次更新. 第一篇谈论一下最近想的比较多的异步的问题. 传统多线程异步 传统的异步是多线程的,当要同时做两件事的时候,他们是执行在不同 ...

  8. 使用express+multer实现node中的图片上传

    使用express+multer实现node中的图片上传 在前端中,我们使用ajax来异步上传图片,使用file-input来上传图片,使用formdata对象来处理图片数据,post到服务器中 在n ...

  9. 简单剖析Node中的事件监听机制(一)

    使用js的class类简单的实现一个事件监听机制,不同于浏览器中的时间绑定与监听,类似于node中的时间监听,并且会在接下来的文章中去根据自己的理解去写一下Event模块中的原理. Node.js使用 ...

随机推荐

  1. 20190804-Python基础 第一章

    学习爬虫的同时,补充学习更多Python的基础知识,才能让所学更加扎实. 至今,所学的很多东西,基础都不牢固,导致这些所学都是浅尝则止的皮毛,不能真正上战场,故借速成之心,踏实打牢基础,举一反三,以求 ...

  2. 字典的setdefault()

    setdefault(key, default) 函数 ---有key获取值.没key设置 key:default dict.setdefault(key, default=None) 如果 key ...

  3. Unable to find optional library: org.apache.http.legacy 错误

    在目录adt-bundle-windows-x86_64-20140702\sdk\platforms\android-20或者 C:\Users\Administrator\AppData\Loca ...

  4. Date及DateFormat用法

    Date 与DateFormat之间的转化String <————>Date Date与Calendar 之间的转化Long<————>Date 日历小程序 Scanner i ...

  5. poj 1224

    题意:有一个5 * 6的矩阵,每个位置表示灯,1表示灯亮,0表示灯灭. 然后如果选定位置i,j点击,则位置i,j和其上下左右的灯的状态都会反转. 现在要你求出一个5 * 6的矩阵,1表示这个灯被点击过 ...

  6. boost random library的使用

      生成满足一定分布的随机数,是统计模拟.系统仿真等应用中最基本的要求.matlab中提供了函数可以生成各种常见分布的随机数,c++使用boost random库也可以很容易实现. 一.例子 boos ...

  7. Maven错误:警告Classpath entry org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER will not be exported or published

    该错误是在我将一个普通的由maven管理的java项目变为javaweb项目后出现的,由警告可以看出是说maven的类路径容器不会被导出或发布(即通过maven管理的依赖不会被导出或发布),那么我们用 ...

  8. BFC渲染机制

    BFC(block formatting context):块级格式化上下文(实际就是一个隔离罩) W3C CSS2.1 规范中的一个概念.它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元 ...

  9. 【转】Fetch超时设置和终止请求

    原文链接:https://www.cnblogs.com/yfrs/p/fetch.html 1.基本使用 Fetch 是一个新的端获取资源的接口,用于替换笨重繁琐XMLHttpRequest.它有了 ...

  10. span元素

    <span>标签属于行内元素(inline),所以无法设置高度和宽度: 如果需要改变其宽高,就需要将其转变为块体元素(block)或行内块体元素(inle-block)