koa vs express

总结:
Express 封装、内置了很多中间件,比如 connect和 router,而 KOA 则比较轻量,开发者可以根据自身需求定制框架;
Express 是基于 callback 来处理中间件的,而 KOA 则是基于 await/async;
在异步执行中间件时,Express 并非严格按照洋葱模型执行中间件,而 KOA 则是严格遵循的。
Express 使用 callback捕获异常,对于深层次的异常捕获不了,Koa 使用 try catch,能更好地解决异常捕获。

express demo

const express = require('express')
const path = require('path')
const fs = require('fs')

const app = express()

function sleep(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time);
  })
}

app.use(async function(req, res, next) {
  console.log('middleware1 start', new Date().getTime());
  // await sleep(1000).then(next);
  next()
  console.log('middleware1 end', new Date().getTime());
})

app.use(async function(req, res, next) {
  console.log('middleware2 start', new Date().getTime());
  // await sleep(2000).then(next);
  next()
  console.log('middleware2 end', new Date().getTime());
})

app.get('/', (req, res, next) => {
  res.send('Hello express ')
})



app.listen(7777, () => {
  console.log('7777 server on...');
})

/**
 * 
 * async await
middleware1 start 1639029830146
middleware2 start 1639029831154
middleware1 end 1639029831154
middleware2 end 1639029833165
 */

/**
 * 
middleware1 start 1639029881890
middleware2 start 1639029881891
middleware2 end 1639029881898
middleware1 end 1639029881898
 */

koa demo

const Koa = require('koa')

const KoaRouter = require('koa-router')

const app = new Koa();

const router = new KoaRouter();

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time));
}

app
  .use(router.routes())
  .use(router.allowedMethods())

router.use(async function (ctx, next) {
  console.log('middleware1 start', new Date().getTime());
  // await sleep(1000).then(next);
  next()
  console.log('middleware1 end', new Date().getTime());
})

router.use(async function (ctx, next) {
  console.log('middleware2 start', new Date().getTime());
  // await sleep(2000).then(next);
  next()
  console.log('middleware2 end', new Date().getTime());
})

router.get('/', (ctx, next) => {
  ctx.body = 'hello koa';
});

app.listen(8888, function () {
  console.log('server start');
})

/**
 * 启动服务时会调用callback
 listen(...args) {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen(...args);
} 
callback中调用compose方法获取promise处理后的中间件
callback() {
  const fn = compose(this.middleware);

  if (!this.listenerCount('error')) this.on('error', this.onerror);

  const handleRequest = (req, res) => {
    const ctx = this.createContext(req, res);
    return this.handleRequest(ctx, fn);
  };
  return handleRequest;
}
compose中dispatch递归调用
 function compose (middleware) {
  if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
  for (const fn of middleware) {
    if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
  }
  return function (context, next) {
    // last called middleware #
    let index = -1
    return dispatch(0)
    function dispatch (i) {
      if (i <= index) return Promise.reject(new Error('next() called multiple times'))
      index = i
      let fn = middleware[i]
      if (i === middleware.length) fn = next
      if (!fn) return Promise.resolve()
      try {
        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
      } catch (err) {
        return Promise.reject(err)
      }
    }
  }
}

use 的时候会把中间件放到数组中this.middleware.push(fn)
use(fn) {
  if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
  if (isGeneratorFunction(fn)) {
    deprecate('Support for generators will be removed in v3. ' +
              'See the documentation for examples of how to convert old middleware ' +
              'https://github.com/koajs/koa/blob/master/docs/migration.md');
    fn = convert(fn);
  }
  debug('use %s', fn._name || fn.name || '-');
  this.middleware.push(fn);
  return this;
}
 */

/** async await
middleware1 start 1639029988309
middleware2 start 1639029989311
middleware2 end 1639029991316
middleware1 end 1639029991316
 */

/**
middleware1 start 1639030056718
middleware2 start 1639030056718
middleware2 end 1639030056719
middleware1 end 1639030056719
 */
posted @ 2021-12-09 14:38  Samsara315  阅读(60)  评论(0编辑  收藏  举报