创建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. JAVA中线程到底起到什么作用!

    这是javaeye上非常经典的关于线程的帖子,写的非常通俗易懂的,适合任何读计算机的同学. 线程同步 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread ...

  2. 指针生成网络(Pointer-Generator-Network)原理与实战

    指针生成网络(Pointer-Generator-Network)原理与实战   阅读目录 0 前言 1 Baseline sequence-to-sequence 2 Pointer-Generat ...

  3. async/await 的引用

    static async void Start() { string s = "ass"; Console.WriteLine(getMemory(s)+"Hello W ...

  4. Vector , list 和 deque的区别

     vector   表示一段连续的内存区域,每个元素被顺序存储在这段内存中,对vector   的随机访问效率很高,但对非末尾元素的插入和删除则效率非常低.  deque    也表示一段连续的内存区 ...

  5. RabbitMQ的基本概念与原理(一)

      1.什么是MQ? MQ全称为Message Queue, 顾名思义,即消息队列,它是一种应用程序对应用程序的通信方法.MQ是消费-生产者模型的一个典型的代表,生产者不断的往消息队列中不断写入消息, ...

  6. Linux 虚拟机扩容

    由于在装软件,原来的20G空间不够使用,需要扩容操作. 1.关闭虚拟机 2.点击编辑虚拟机设置 选中硬盘,添加,硬盘,推荐,确定大小,完成. 2.启动虚拟机 查看磁盘使用情况: [root@maste ...

  7. Redis分布式缓存安装和使用

    独立缓存服务器: LinuxCentOS Redis版本: 3.0 下面我们针对于Redis安装做下详细的记录: 编译和安装所需的包: #yum install gcc tcl创建安装目录:贵州中医肝 ...

  8. python 之math模块

    一.math 简介 import math # 导入模块 ret = dir(math) # 查看所有函数名列表 print(ret) # ['__doc__', '__loader__', '__n ...

  9. idHTTP.Post

    procedure TForm4.Button2Click(Sender: TObject); var sResponse: string; EnvStr : TStringStream; begin ...

  10. 一图一知-TS之Interface接口