最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 一个前端会经常遇到的问题

    正文概述 掘金(Peter谭老师)   2021-02-04   554

    从一个前端经常会遇到的问题

    • 例如,我想要在一个项目里,监听所有的fetch请求,应该怎么办?又或者说,我想用别人封装好的方法,但是在它之前,需要经过一层处理、判断,然后再看情况是否调用别人封装好的方法
    • 这种需求,大都是相似的,记得我之前讲解过koa洋葱圈、redux中间件等源码是我们前端的一种核心解决问题的思维方式

    从如何监听fetch请求说起

    • 例如,fetch的使用,一般是:
    fetch(url).then((res)=>{...})
    
    • 那么对于一个已经使用过很多次的项目,我需要监听这个fetch请求。应该怎么办呢?很简单,我们“重写”fetch
     const myFetch = window.fetch;
     window.fetch = function (...arg) {
          console.log("此时调用了fetch,参数是:", arg);
          return myFetch(arguments);
        };
     fetch("www.baidu.com").then((res) => {
          console.log(res, "res");
        });
    
    • 简单的几行代码,就实现了监听所有的fetch请求。而且不会对原有的功能有入侵,不过问题来了

    一个前端会经常遇到的问题

    • 这样做,其实相当于去修改原型链上的方法,导致纯净的原有方法被污染。真正操作时候,建议新写一个方法,然后全局替换即可,这样能保证底层的fetch方法是正常的,不会影响那些不需要log的地方,那么我们今天顺便讲讲类似的源码实现

    到redux最精髓的中间件源码compose函数

    • 比如说我们有这样几个函数:
    function add1(str) {
        return str + 1
    }
    
    function add2(str) {
        return str + 2
    }
    
    function add3(str) {
        return str + 3
    }
    
    • 我们想依次执行函数,并把执行结果传到下一层就要像下面一样一层套一层的去写:
    let newstr = add3(add2(add1("abc"))) //"abc123"]
    
    • 这只是3个,如果数量多了或者数量不固定处理起来就很麻烦,但是我们用compose写起来就很优雅:
    let newaddfun = compose(add3, add2, add1);
    let newstr = newaddfun("abc") //"abc123"
    
    那compose内部是如何实现的呢?
    function compose(...funcs) {
        return funcs.reduce((a, b) => (...args) => a(b(...args)));
    }
    
    • 其实核心代码就一句,这句代码使用了reduce方法巧妙地将一系列函数转为了add3(add2(add1(...args)))这种形式,我们使用上面的例子一步一步地拆分看一下
    • 当调用compose(add3, add2, add1)funcs是add3, add2, add1,第一次进入时a是add3b是add2,展开就是这样子: (add3, add2)=>(...args)=>add3(add2(...args)),传入了add3, add2,返回一个这样的函数(...args)=>add3(add2(...args)),然后reduce继续进行,第二次进入时a是上一步返回的函数(...args)=>add3(add2(...args))b是add1,于是执行到a(b(...args)))时,b(...args)作为a函数的参数传入,变成了这种形式:(...args)=>add3(add2(add1(...args))),是不是很巧妙。

    再到promise链式调用实现

    • Promise链式调用跟JQ的区别在于,promise.then每次返回的都是一个新的promise实例对象,这样实现了链式调用。
    • JQ链式,相当于一个函数内部永远都返回当前这个相同的this
    //这里我也忘了是不是这样用了
    $('#root').style(...).style(...)
    
    • Promise链式,最后打印结果是Peter老师666,每次.then返回的是一个新的Promise
    Promise.resolve("Peter老师666")
      .then((res) => {
        return res;
      })
      .then((res) => {
        console.log(res,'res')
        return res;
      });
    
    

    再到express的next

    • 当我们在路由处理中调用next()时候,就会进入下一个匹配,例如当我们用get请求接口test时候,就会走到 console.log("此时被触发")这行代码
    app.get('/test',(req,res,next)=>{
      next()
      
    })
    app.get('*',(req,res,next)=>{
      console.log("此时被触发")
    })
    
    • 原因是什么?实现express的next很简单
      handle(req, res, matchedList) {
        const next = () => {
          const midlleware = matchedList.shift();
          if (midlleware) {
            midlleware(req, res, next);
          }
        };
        next();
      }
    
    • 我们先找到所有匹配的请求方式和路由,然后首先处理第一个匹配中的路由,使用闭包方式传入next方法。当调用next方法时候,会执行下一个匹配中的路由回调函数。这样就实现了next

    再到koa的中间件

    • 怎么使用koa的中间件?
    app.use(middlewaer1).use(middlewaer2).use(middlewaer3)
    
    • 是不是感觉跟JQ的链式调用很像,其实一样,都是统一返回this即可。如下所示:
    const obj = {
      print(arg) {
        console.log(arg);
        return this;
      },
      hello(arg) {
        console.log(arg);
        return this;
      },
      world(arg) {
        console.log(arg);
        return this;
      },
    };
    obj.print('Peter').print('hello').print('world');
    
    • 此时控制台就输出了Peter,hello,world。我们实现了最简单的链式调用.

    总结

    • 看了这么多,本文最有难度的,恐怕就是compose函数。其实大多数源码都是类似的,掌握其精华,去其糟粕才能收益最大化。
    • 如果感觉写得不错,来个在看/赞/转发三连吧,关注下我的公众号:【前端巅峰】谢谢支持我的原创!

    起源地下载网 » 一个前端会经常遇到的问题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元