首先我们看下中间件的运作机制,当一个被加【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】入到中间件pipe列表中的中间件开始处理转载请注明出处:www.tangshuang.net【版权所有,侵权必究】传入的内容时,它需要调用一个next,通【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。过next来触发下一个中间件,如果没有下转载请注明出处:www.tangshuang.net【作者:唐霜】一个,则表示所有中间件已经处理完毕,进入【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】正常的处理程序。而如果没有执行next函原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net数,则进程被block住,处于一直等待状【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net态,这样,我们就可以在中间件中进行异步处转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。理,在异步处理的回调中去执行next函数著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。。
原创内容,盗版必究。【未经授权禁止转载】原创内容,盗版必究。转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net那么,怎能在js中实现这种机制呢?我们来未经授权,禁止复制转载。未经授权,禁止复制转载。看下超简洁的代码实现:
【转载请注明来源】【版权所有,侵权必究】【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。/**
* @desc process with a pipe line
* @param array middlewares: a middleware is a function which like `function deal(args, next, stop) {}`,
* in this function, you can modify args and use `next(args)` to pass it to next middleware,
* next middleware will recieve `next(args)`'s `args` as first parameter,
* or use `stop()` to stop process
* @param any params, will be used as the first middleware's first parameter.
* @return a promise
*/
export default function crossPipeLine(params, middlewares) {
return new Promise((resolve, reject) => {
let i = 0;
// if middlewares is not as expected
if (!Array.isArray(middlewares)) {
middlewares = typeof middlewares === "function" ? [middlewares] : [];
}
// remove no use middlewares
middlewares = middlewares.filter((item) => !!item);
let roll = (args) => {
let pipe = middlewares[i];
if (!pipe) {
resolve(args);
return;
}
i++;
return new Promise((next, stop) => pipe(args || params, next, stop)).then(roll).catch(reject);
};
roll(params);
});
}
上面这段代码,创建了一个通道处理器,在处【原创不易,请尊重版权】【原创不易,请尊重版权】理器中执行中间件函数,全部执行完之后,返著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。回一个promise。看下一个中间件函数转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。怎么写:
著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.netfunction myMiddleware(req, next, stop) {
// modify req
next(req)
}
其中,红色的next和stop是两个固定著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】参数,都是函数,放在middleware本文版权归作者所有,未经授权不得转载。【转载请注明来源】函数的最后两个参数位置,前面的req是自未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。定义参数,且只有这一个自定义参数(数据类【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】型可以根据自己的情况传入),比如myMi原创内容,盗版必究。【转载请注明来源】ddleware([1, 2, 3], 【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】next)或者myMiddleware(【本文受版权保护】【关注微信公众号:wwwtangshuangnet】{ a: 1 }, next),stop著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。是可以省略的,但是next不可以省略,因【转载请注明来源】未经授权,禁止复制转载。为如果不执行next或stop中的任何一【原创不易,请尊重版权】【原创内容,转载请注明出处】个,那么程序会停滞在这里,不会继续往下执【未经授权禁止转载】转载请注明出处:www.tangshuang.net行。
著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】next的参数是传给下一个中间件函数的第【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。一个参数。比如上面这里的next(req【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。),那么在下一个中间件myMiddlew转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】are2(req, next, stop【作者:唐霜】本文作者:唐霜,转载请注明出处。)里面的req就来自于next。在一些情本文作者:唐霜,转载请注明出处。【作者:唐霜】况下next可以不传参数,比如你在中间件转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】里面直接修改了req,由于req是个对象本文作者:唐霜,转载请注明出处。原创内容,盗版必究。,是引用型数据,所以在下一个中间件里面,未经授权,禁止复制转载。【原创不易,请尊重版权】你使用req时,已经是被修改过的。这种情【作者:唐霜】【关注微信公众号:wwwtangshuangnet】况下,可以不给next传参,不传参的情况本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net,实际上是把当前中间件接收到的第一个参数原创内容,盗版必究。【版权所有,侵权必究】传给下一个中间件,但如果你想传递字符串或【本文受版权保护】著作权归作者所有,禁止商业用途转载。数字或boolean,就必须要通过nex未经授权,禁止复制转载。【未经授权禁止转载】t传入。
【作者:唐霜】转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】【转载请注明来源】接下来,看下如何在一个项目中如何使用这个本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】通道处理器:
【原创内容,转载请注明出处】【未经授权禁止转载】本文作者:唐霜,转载请注明出处。【作者:唐霜】let myMiddlewares = [ myMiddleware ] let newReq = await crossPipeLine(req, myMiddlewares)
这样就实现了一个非常简洁的中间件机制。转载请注明出处:www.tangshuang.net
本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。2017-12-16 5104


