美文网首页
Express, Koa, Redux中间件的区别,写法和执行流

Express, Koa, Redux中间件的区别,写法和执行流

作者: rxdxxxx | 来源:发表于2018-07-29 17:50 被阅读261次

    1. 区别

    Express

    Express 是一个自身功能极简,完全是由路由和中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。

    中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。

    如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。

    Koa

    Koa目前主要分1.x版本和2.x版本,它们最主要的差异就在于中间件的写法,

    Redux

    redux的middleware是提供的是位于 action 被发起之后,到达 reducer 之前的扩展点

    对比

    框架 异步方式
    Express callback
    Koa1 generator/yield+co
    Koa2 Async/Await
    Redux redux-thunk,redux-saga,redux-promise等

    2. 写法

    Express

    //Express
    var express = require('express')
    var app = express()
    app.get('/',(req,res)=>{
        res.send('Hello Express!')
    })
    app.listen(3000)
    

    Koa1

    var koa = require('koa');
    var app = koa();
    
    // logger
    
    app.use(function *(next){
      var start = new Date;
      yield next;
      var ms = new Date - start;
      console.log('%s %s - %s', this.method, this.url, ms);
    });
    
    // response
    
    app.use(function *(){
      this.body = 'Hello World';
    });
    
    app.listen(3000);
    

    Koa2

    const Koa = require('koa');
    const app = new Koa();
    
    // logger
    // common function 最常见的,也称modern middleware
    app.use((ctx, next) => {
      const start = new Date();
      return next().then(() => {
        const ms = new Date() - start;
        console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
      });
    });
    
    // logger
    // generatorFunction 生成器函数,就是yield *那个
    app.use(co.wrap(function *(ctx, next) {
      const start = new Date();
      yield next();
      const ms = new Date() - start;
      console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
    }));
    
    // logger
    // async function 最潮的es7 stage-3特性 async 函数,异步终极大杀器
    app.use(async (ctx, next) => {
      const start = new Date();
      await next();
      const ms = new Date() - start;
      console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
    });
    
    // response
    app.use(ctx => {
      ctx.body = 'Hello Koa';
    });
    
    app.listen(3000);
    

    Redux

    import { createStore, applyMiddleware } from 'redux'
    /** 定义初始 state**/
    const initState = {
      score : 0.5
    }
    /** 定义 reducer**/
    const reducer = (state, action) => {
      switch (action.type) {
        case 'CHANGE_SCORE':
          return { ...state, score:action.score }
        default:
          break
      }
    }
    
    /** 定义中间件 **/
    const logger = ({ dispatch, getState }) => next => action => {
      console.log('【logger】即将执行:', action)
    
      // 调用 middleware 链中下一个 middleware 的 dispatch。
      let returnValue = next(action)
    
      console.log('【logger】执行完成后 state:', getState())
      return returnValue
    }
    
    /** 创建 store**/
    let store = createStore(reducer, initState, applyMiddleware(logger))
    
    /** 现在尝试发送一个 action**/
    store.dispatch({
      type: 'CHANGE_SCORE',
      score: 0.8
    })
    /** 打印:**/
    // 【logger】即将执行: { type: 'CHANGE_SCORE', score: 0.8 }
    // 【logger】执行完成后 state: { score: 0.8 }
    
    

    3. 执行流程

    Express

    其实express middleware的原理很简单,express内部维护一个函数数组,这个函数数组表示在发出响应之前要执行的所有函数,也就是中间件数组,每一次use以后,传进来的中间件就会推入到数组中,执行完毕后调用next方法执行函数的下一个函数,如果没用调用,调用就会终止。

    express的请求

    Koa

    Koa会把多个中间件推入栈中,与express不同,koa的中间件是所谓的洋葱型模型。

    Koa中间件原理
    var koa = require('koa');
    var app = koa();
    
    app.use(function*(next) {
      console.log('begin middleware 1');
      yield next;
      console.log('end middleware 1');
    });
    
    app.use(function*(next) {
      console.log('begin middleware 2');
      yield next;
      console.log('end middleware 2');
    });
    
    app.use(function*() {
      console.log('middleware 3');
    });
    
    app.listen(3000);
    
    // 输出
    begin middleware 1
    begin middleware 2
    middleware 3
    end middleware 2
    end middleware 1
    

    Redux

    dispatch流程

    从上图中得出结论,middleware通过next(action)一层层处理和传递action直到redux原生的dispatch。而如果某个middleware使用store.dispatch(action)来分发action,就相当于重新来一遍。

    在middleware中使用dispatch的场景一般是接受一个定向action,这个action并不希望到达原生的分发action,往往用在一步请求的需求里,如redux-thunk,就是直接接受dispatch。

    如果一只简单粗暴调用store.dispatch(action),就会形成无限循环。

    参考文章

    Redux,Koa,Express之middleware机制对比

    koa,redux等主流框架的中间件设计思想原理分析

    Koa入门, 中间件介绍

    理解 Koa 的中间件机制

    Redux, Middleware

    相关文章

      网友评论

          本文标题:Express, Koa, Redux中间件的区别,写法和执行流

          本文链接:https://www.haomeiwen.com/subject/swctvftx.html