【koa快速入门】之基础使用

821 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

koa系列

本文是koa快速入门系列的第一篇

前言

本文是koa快速入门的第一篇:基础使用,后续还会再写两篇文章,介绍「koa项目最佳实践」和「深究koa原理」。

《koa2教程》思维导图

简介

koa是Express团队打造的新一代web框架,特点是更小,更舒服的开发体验。

更舒服的开发体验

koa对Express的改进之一,是对异步实现方式的改进。

Express是基于ES5的,其异步写法更常见的是基于回调,当然只要node版本支持,也可以用async/await,但是其自身对async/await没有太多支持,如果用了async/await,在错误处理和中间件执行顺序上要开发者自己解决一些问题。

下面代码是Express使用Promise回调时候的一个异常处理示例。

const express = require("express");
const app = express();

//create a server object:
app.get("/", (req, res, next) => {
  // do some sync stuff
  queryDb()
    .then((data) => {
      res.write("Hello" + data); //write a response to the client
      res.end();
    }) // handle data
    .catch(next);  //catch(next)处理异步代码块中的任何异常
});

app.use((err, req, res, next) => {
  res.write("reject" + err); //write a response to the client
  res.end();
});

// 所有异步代码必须返回 Promise
const queryDb = function () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("hi");
    }, 1000);
  });
};

app.listen(8080, function () {
  console.log("server running on 8080");
}); //the server object listens on port 8080

koa 1.0基于ES6编写,使用generator实现异步,代码看起来是下面这样,已经实现了同步写法写异步。

var koa = require('koa');
var app = koa();

app.use('/test', function *() {
    yield doReadFile1();
    var data = yield doReadFile2();
    this.body = data;
});

app.listen(3000);

koa 2.0基于ES7编写,ES7引入了async/await关键字,使得同步写异步更加方便,于是koa2的异步代码看起来是这样的。

app.use(async (ctx, next) => {
    await next();
    var data = await doReadFile();
    ctx.response.type = 'text/plain';
    ctx.response.body = data;
});

本文的koa都是指koa 2.0版本。

更小更简洁

koa和express另一个区别在于,koa本身不包含任何的中间件,只是一个中间件框架,具体功能都是由各种外部的中间件实现的,而express自带了路由、模板、发送文件、jsonp等等功能,这也使koa框架自身更小更简洁。

使用

示例化应用程序

hello world😄

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

app.listen

app.listen是http.createServer的语法糖。

const Koa = require('koa');
const app = new Koa();
app.listen(3000);

等于

const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);

其中app.callback用于处理成http.createServer适用的回调方法。

app.use

app.use用于把中间件添加到应用程序中,中间件的执行顺序是洋葱模型,这个我们在「深究原理」这一趴再详细说说。

适用方法参考下面这个代码。

const Koa = require('koa');
const app = new Koa();

// x-response-time

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// logger

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});

// response

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

错误处理

「前言」那里,我们看到express的错误处理,其实并不太优雅。

相比之下,koa的错误处理好得多,koa通过添加一个“error”监听器来集中进行错误处理。

app.on('error', (err, ctx) => {
  log.error('server error', err, ctx)
});

路由中间件-koa-router

基本使用

koa-router用于管理url路径

const Koa = require('koa');
const Router = require('@koa/router');

const app = new Koa();
const router = new Router();

router.get('/', (ctx, next) => {
  // ctx.router available
});

router.post('/signin', (ctx, next) => {
  // ctx.router available
});

app
  .use(router.routes())
  .use(router.allowedMethods()); // allowedMethods用于在响应头返回允许的请求方式

参考文档

更高级的操作,参考koa-router

解析中间件-koa-body

基本使用

koa-body用于解析body,支持multipart, urlencoded, and json格式的请求body。

const Koa = require('koa');
const app = new Koa();
const router = require('koa-router')();
const koaBody = require('koa-body');

router.post('/users', koaBody(),
  (ctx) => {
    console.log(ctx.request.body);
    // => POST body
    ctx.body = JSON.stringify(ctx.request.body);
  }
);

app.use(router.routes());

app.listen(3000);
console.log('curl -i http://localhost:3000/users -d "name=test"');

参考文档

更高级的操作,参考koa-body

优化koa项目结构

前面我们都是在介绍在单文件里面使用koa,但是这并不优美,更好的实现方式是把路由(route)、逻辑(controller)等等按功能分块。

遗憾的是,不像express,koa没有官方的生成器,可以按模版生成koa的项目。但是官方提供了一些其他人的最佳实践,可以参考下koa项目示例

作者看了一圈没有找到合心意的模板,于是决定自己实现一下,明天我们会更新一篇文章,介绍一下作者心目中的koa最佳实践(挖坑🕳️),敬请期待😄。

深究原理

koa源码实现和洋葱模型的的实现方式,后天我们再继续更文介绍(挖坑🕳️),敬请期待😄

参考文献

koa2教程

koa官网

KOA2框架原理解析和实现

koa2加载模板引擎

往期好文

“告别烂代码”

2022代码规范最佳实践(附web和小程序最优配置示例)

【前端探索】告别烂代码!用责任链模式封装网络请求

【前端探索】告别烂代码第二期!用策略模式封装分享组件

代码人生

【三年前端开发的思考】如何有效地阅读需求?

前端踩坑必看指南

【前端探索】图片加载优化的最佳实践

【前端探索】移动端H5生成截图海报的探索

【前端探索】H5获取用户定位?看这一篇就够了

【前端探索】微信小程序跳转的探索——开放标签为什么存在?

【前端探索】vConsole花式用法