2024年Web前端最全koa-convert 源码解析(3),前端面试小本本

最后

其实前端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一个复习的路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《前端开发四大模块核心知识笔记》

最后,说个题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

app.use(async (ctx, next) => {
console.log(3333); // 2. 第二步再打印 3333
await next();
console.log(44444); // 3. 第三部打印44444
});
app.listen(3001);
console.log(‘app started at port 3001…’);


当我们在node命令行中使用 node app.js 命令时,然后浏览器中 输入地址:`http://localhost:3001/` 访问的时候,我们可以看到命令中会分别打印



1111
3333
444444
222222.


我们再来看下,Koa源码中的`application.js` 代码如下:在use方法内部,代码如下:



const convert = require(‘koa-convert’);
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;
}


如上koa2源码中的use函数,该函数有一个fn参数,


* 首先判断该fn是不是一个函数,如果不是一个函数的话,直接抛出一个错误,提示,中间件必须为一个函数。
* 第二步继续判断该fn函数是不是一个Generator函数,如果它是generator函数的话,就把该函数使用 koa-convert包转换成async函数。然后把对应的async函数放进 this.middleware数组中。最后返回该对象this。


这上面是koa2中的基本源码,下面我们来看看 koa-convert中的源码是如何做的呢?



const co = require(‘co’)
const compose = require(‘koa-compose’)
module.exports = convert
function convert (mw) {
if (typeof mw !== ‘function’) {
throw new TypeError(‘middleware must be a function’)
}
if (mw.constructor.name !== ‘GeneratorFunction’) {
// assume it’s Promise-based middleware
return mw
}

// co将Generator函数转换成promise对象,然后会自动执行该函数的代码
const converted = function (ctx, next) {
// return 一个Promise函数, 直接调用该Generator函数,返回return yield next(); 返回下一个中间件
return co.call(ctx, mw.call(ctx, createGenerator(next)))
}
converted._name = mw._name || mw.name
return converted
}
function * createGenerator (next) {
return yield next()
}
// convert.compose(mw, mw, mw)
// convert.compose([mw, mw, mw])
convert.compose = function (arr) {
if (!Array.isArray(arr)) {
arr = Array.from(arguments)
}
return compose(arr.map(convert))
}


部分源码如上,首先引入co包中的代码,co的作用是:将Generator函数转换成promise对象,然后会自动执行该函数的代码。


引入 koa-compose包,将koa包中的中间件合并,然后依次执行各个中间件。


**convert 函数**


`convert`函数有一个参数`mw`,首先判断该参数`mw`是不是一个函数,如果该`mw`不是一个函数的话,就直接抛出一个异常提示,该中间件必须是一个函数。


判断该 `mw.constructor.name !== 'GeneratorFunction'` 是不是一个Generator函数,如果不是Generator函数的话,就直接返回该mw。


如果它是Generator函数的话,就会执行 converted 函数,该函数有2个参数,第一个参数ctx是运行Generator的上下文,第二个参数是传递给Generator函数的next参数。


最后返回 `return co.call(ctx, mw.call(ctx, createGenerator(next)))`; co的作用是将一个Generator函数,转为一个Promise函数,然后该Generator函数会自动执行。createGenerator函数代码如下:



function * createGenerator (next) {
return yield next()
}


因此 `mw.call(ctx, createGenerator(next))`,如果mw是一个Generator函数的话,就直接调用该Generator函数,返回`return yield next()`;


返回下一个中间件,然后使用调用co包,使返回一个Promise对象。该本身对象的代码会自动执行完。


在convert函数代码中,有一句代码 `mw.constructor.name !== 'GeneratorFunction'` 是不是一个Generator函数。  
 可以如上面进行判断,比如如下代码演示是否是Generator函数还是AsyncFunction函数了,如下代码:



function* test () {};
console.log(test.constructor.name); // 打印 GeneratorFunction
async function test2() {};
console.log(test2.constructor.name); // 打印 AsyncFunction


如上所有的分析是 convert 函数的代码了,该代码一个最主要的作用,判断传递进来的mw参数是不是Generator函数,如果是Generator函数的话,就把该Generator函数转化成使用co包装成Promise对象了。


**back函数**


代码如下:



convert.back = function (mw) {
if (typeof mw !== ‘function’) {

总结

根据路线图上的重点去进行有针对性的学习,在学习过程中,学会写笔记,做总结。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

这里分享一些前端学习笔记:

  • html5 / css3 学习笔记

  • JavaScript 学习笔记

  • Vue 学习笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值