一个从 fetch 扩展出来的骚操作,甚至还可以推广到其他内置函数

920 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动


在 js 中,没有函数重载的概念。又由于不存在继承关系,没法做到函数重写,有的只是函数定义覆盖😧

现在,我们对系统内置的函数,做功能增强,表现为对输入的参数做校验检查在方法执行前和后,做我们期望的一些事情

fetch 为例,在js中,我们先使用一个临时变量 old 接受这个函数,同时,对 fetch进行函数覆盖,前两项我们传入了和原方法一致的参数,同时追加了第 3 个参数:回调方法

在函数执行之前,我们打印了一下 url,如果在业务中,我们可以在不修改代码的情况下,统计出 fetch 调用时请求了哪些 url,以及他们请求的次数;或者是,对返回的结果做统一的解析并记录异常数据

应用场景

在前期,由于设计的缺陷,导致我们没有对相关的操作方法进行封装,后期又需要做统一的操作,但是直接去重构,改动的地方会很多

内置函数识别

如果我们需要重写内置的函数,我们仅仅需要改动一次即可,而不是重复覆盖以免出现异常

查阅资料,内置的函数是不会具备 prototype 属性

内置函数重构模版

fetch 为例

{
    if (fetch.prototype == undefined) {
        let old = window.fetch;
        fetch = function(url, httpConfig, beforeFn = () => {}, afterFn = (d) => console.log(d), callback = (d)=>{}) {
            beforeFn();
            let result = old(url, httpConfig);
            afterFn();
            return result;
        }
    }
}

fetch 优化

如果调用的时候,指定了解析的方式,直接通过回调函数处理结果;如果不指定或者指定的类型不符合设定,直接返回原始 fetch 的请求结果,一个 Promise 对象

{
    if (fetch.prototype == undefined) {
        let old = window.fetch;
        // 不传 type 或者传递的 type 没有处理
        fetch = function(url, httpConfig, type, callback = (d) => console.log(d)) {
            console.log('fetch', url);
            let fns = {
                'json': rep => rep.json(),
                'text': rep => rep.text(),
            }
            if (type == null || fns[type] == undefined) return old(url, httpConfig);
            old(url, httpConfig).then(fns[type]).then(data => callback(data));
        }
    }
}

相比于原始调用,还是方便了那么一点点,不用写2步 then 来转化得到实际数据,但在这个方法执行的前和后所追加的切面处理,应该算是一个巨大的进步

image.png

碎碎念

我坦白,搞这玩意,想着看能否拦截掘金里的 fetch 请求,要是成了,就知道对应的 url,就可以拿到里面的 aid 和 uuid,然后,我的抽奖插件就更加好使了