2024年前端最新koa-convert 源码解析,程序员的面试题

总结一下

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

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

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

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') {
    throw new TypeError('middleware must be a function')
  }
  if (mw.constructor.name === 'GeneratorFunction') {
    // assume it's generator middleware
    return mw
  }
  const converted = function \* (next) {
    let ctx = this
    let called = false
    // no need try...catch here, it's ok even `mw()` throw exception
    yield Promise.resolve(mw(ctx, function () {
      if (called) {
        // guard against multiple next() calls
        // https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36
        return Promise.reject(new Error('next() called multiple times'))
      }
      called = true
      return co.call(ctx, next)
    }))
  }
  converted._name = mw._name || mw.name
  return converted
}



###  总结

大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)**

![](https://img-blog.csdnimg.cn/img_convert/718310d106ab948d6f467d78e08b1aed.png)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值