js中间件

当我们在编写业务代码时候,我们无法避免有些业务逻辑复杂而导致业务代码写得又长又乱,如果再加上时间紧凑情况下写出来的代码估计会更让人抓狂。以至于我们一直在寻求更好的架构设计和更好的代码设计,这是一个没有终点的求知之路,但是在这条路上会越走越好。

在前端,我们可以借用这种思想通过before和after函数来实现:

Function.prototype.before = function(fn){//函数处理前执行fn
var self = this;
return function(){
fn.call(this);
self.apply(this, arguments);
}
}
Function.prototype.after = function(fn){//函数处理后执行fn
var self = this;
return function(){
self.apply(this, arguments);
fn.call(this);
}
}

实现思路是对被处理的函数通过闭包封装在新的函数里,在新的函数内部按照顺序执行传入的参数fn和被处理的函数。

1 举个例:

用户提交表单数据之前需要用户行为统计,代码应该是这样写:

function report(){
console.log('上报数据');
}
function submit(){
console.log('提交数据');
} submit.before(report)(); //提交之前执行report
//结果: 上报数据
// 提交数据

从代码可以看出已经把统计和数据提交业务隔离起来,互不影响。

但是如果提交数据之前,需要数据验证并且依据验证结果判断是否能提交,怎么做?这里要改动before函数,看下代码:

Function.prototype.before = function(fn){//函数处理后执行fn
var self = this;
return function(){
var res = fn.call(this);
if(res)//返回成功则执行函数
self.apply(this, arguments);
}
} function report(){
console.log('上报数据');
return true;
}
function validate(){
console.log('验证不通过');
return false;
}
function submit(){
console.log('提交数据');
} submit.before(report).before(validate)();
//结果:
// 验证不通过 function report(){
console.log('上报数据');
return true;
}
function validate(){
console.log('验证通过');
return true;
}
function submit(){
console.log('提交数据');
} submit.before(report).before(validate)();
//结果:
// 验证通过
// 上报数据
// 提交数据

上面的例子如果很复杂会出现很长的链式,后期维护也很容易看晕,并且before和after也没有考虑到异步操作,显然还是有些不足的,那么还有没有其他解决办法呢,既能隔离业务,又能方便清爽地使用~我们可以先看看其他框架的中间件解决方案。

2 express

express是非常轻量的框架,express是集合路由和其他几个中间件合成的web开发框架,koa是express原班人马重新打造一个更轻量的框架,所以koa已经被剥离所有中间件,甚至连router中间件也被抽离出来,任由用户自行添加第三方中间件。解析express的写法

express的中间件写法如下:

var express = require('express');
var app = express(); app.use(function(req, res, next) {
console.log('数据统计');
next();//执行权利传递给
}); app.use(function(req, res, next) {
console.log('日志统计');
next();
}); app.get('/', function(req, res, next) {
res.send('Hello World!');
}); app.listen(3000);
//整个请求处理过程就是先数据统计、日志统计,最后返回一个Hello World!

从上图来看,每一个“管道”都是一个中间件,每个中间件通过next方法传递执行权给下一个中间件,express就是一个收集并调用各种中间件的容器。

中间件就是一个函数,通过express的use方法接收中间件,每个中间件有express传入的req,res和next参数。如果要把请求传递给下一个中间件必须使用 next() 方法。当调用res.send方法则此次请求结束,node直接返回请求给客户,但是若在res.send方法之后调用next方法,整个中间件链式调用还会往下执行,因为当前hello world所处的函数也是一块中间件,而res.send只是一个方法用于返回请求。

3 参照express我们可以仿写

我们可以借用中间件思想来分解我们的前端业务逻辑,通过next方法层层传递给下一个业务。做到这几点首先必须有个管理中间件的对象,我们先创建一个名为Middleware 的对象:

function Middleware(){
this.cache = [];
}

Middleware通过数组缓存中间件。下面是next和use 方法:

Middleware.prototype.use = function(fn){
if(typeof fn !== 'function'){
throw 'middleware must be a function';
}
this.cache.push(fn);
return this;
} Middleware.prototype.next = function(fn){
if(this.middlewares && this.middlewares.length > 0 ){
var ware = this.middlewares.shift();
ware.call(this, this.next.bind(this));
}
}
Middleware.prototype.handleRequest = function(){//执行请求
this.middlewares = this.cache.map(function(fn){//复制
return fn;
});
this.next();
}

我们用Middleware简单使用一下:

  var middleware = new Middleware();
middleware.use(function(next){console.log(1);next();})
middleware.use(function(next){console.log(2);next();})
middleware.use(function(next){console.log(3);})
middleware.use(function(next){console.log(4);next();})
middleware.handleRequest();
//输出结果:
//1
//2
//3
// 4没有出来是因为上一层中间件没有调用next方法,我们升级一下Middleware 高级使用 var middleware = new Middleware();
middleware.use(function(next){
console.log(1);next();console.log('1结束');
});
middleware.use(function(next){
console.log(2);next();console.log('2结束');
});
middleware.use(function(next){
console.log(3);console.log('3结束');
});
middleware.use(function(next){
console.log(4);next();console.log('4结束');
});
middleware.handleRequest();
//输出结果:
//1
//2
//3
//3结束
//2结束
//1 结束

每一个中间件执行权利传递给下一个中间件并等待其结束以后又回到当前并做别的事情,方法非常巧妙。

原文链接:https://www.cnblogs.com/wjd2221/p/7364221.html

JS第三方中间件的延伸的更多相关文章

  1. Node.js + Express中间件详解

    使用中间件 Express是一种路由和中间件Web框架,它具有自己的最小功能:Express应用程序本质上是一系列中间件函数调用. 中间件函数是可以访问请求对象 (req),响应对象(res)以及应用 ...

  2. 高性能的js第三方库——lodash、 Underscore、async、md5及moment

    背景:为了实现某些功能,如:数据排序.分组.筛选.深拷贝等,自己写的函数或网上搜索处理的转换函数质量无法保证,这时直接使用成熟的js第三方库是首选. *注:“framework(框架)”,“libra ...

  3. express第三方中间件研究之bodyParser中间件

    转载至:http://www.cnblogs.com/lianer/p/5178693.html 接触nodejs已有一段时间了,但最近才开始落实项目,于是使用express应用生成器生成了一个应用. ...

  4. Nest.js 添加中间件

    Docs: https://docs.nestjs.com/middleware 创建中间件 logger.middleware.ts import { Injectable, NestMiddlew ...

  5. Node.js 第三方包的安装、升级、卸载,以及包依赖管理

    本地安装: npm install package-name 全局全装: npm install -g  package-name 举个栗子 全局安装 React项目的脚手架 npm install ...

  6. node.js 的 中间件 初理解

    听说中间件还挺重要,下面梳理一下初认识: 中间件是什么?简单说说http请求服务的过滤,当交给函数处理之前先交给它处理.匹配后会终止,要想再匹配,得加: next. 中间件能解决什么问题?检测用户登录 ...

  7. js第三方

    1.0 https://github.com/aui/artDialog 2.0 前端开发仓库 http://code.ciaoca.com/ 3.0 打赏 https://github.com/gr ...

  8. 小程序中怎么引入wepy.js第三方toast组件

    1.先安装组件 npm install wepy-com-toast --save 2.引入wepy和toast import wepy from 'wepy' import Toast from ' ...

  9. 字符串编码js第三方类库text-encoding

    GITHUB地址:https://github.com/BCode001/text-encoding

随机推荐

  1. 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时3

    课时3 计算机视觉历史回顾与介绍下 ImageNet有5000万张图片,全部都是人工清洗过得,标注了超过2万个分类. CS231n将聚焦于视觉识别问题,图像分类关注的是大图整体:物体检测告诉你东西具体 ...

  2. bzoj 3053: The Closest M Points【KD-tree】

    多维KDtree板子 左右儿子的估价用mn~mx当区间,假设区间里的数都存在:k维轮着做割点 #include<iostream> #include<cstdio> #incl ...

  3. Python 字符串太长分行写

    原文:https://blog.csdn.net/peng__dada/article/details/79138135 #第一种:三个单引号 print '''我是一个程序员       我刚开始学 ...

  4. Spring Boot中使用Swagger2构建RESTful APIs介绍

    1.添加相关依赖 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <depen ...

  5. 51Nod 1116 K进制下的大数(暴力枚举)

    #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> us ...

  6. Counting The Important Pairs CodeChef - TAPAIR

    https://vjudge.net/problem/CodeChef-TAPAIR 合法的删除方法: 第一种:桥边与其余任意边(1)桥*(桥-1)/2(两条桥边)(2)桥*(m-桥)(桥边+其他边) ...

  7. queue+模拟 Codeforces Round #304 (Div. 2) C. Soldier and Cards

    题目传送门 /* 题意:两堆牌,每次拿出上面的牌做比较,大的一方收走两张牌,直到一方没有牌 queue容器:模拟上述过程,当次数达到最大值时判断为-1 */ #include <cstdio&g ...

  8. Kruskal HDOJ 1863 畅通工程

    题目传送门 /* 此题为:HDOJ 1233 + HDOJ 1232 */ #include <cstdio> #include <algorithm> #include &l ...

  9. 三色灯渐变DIY制作

    小编前几天查资料,怎么使用12864屏幕的用法,突然发觉微博是个好东西,随着自己的成长,学习了很多的知识,没有做笔记的习惯,只是习惯把用到的硬件,传感器,资料写到程序的备注内,但感觉,用到时不是那么方 ...

  10. 生产环境中使用脚本实现tomcat start|status|stop|restart

    一.在实际生产环境中tomcat启动是在bin目录下采用自带脚本startup.sh启动:使用shutdown.sh关闭.如下图: 再如果对于新手来讲在不知道路径情况下重启是一件头痛的事情(注意没有r ...