• webpack loader的加载顺序(从右向左,从下向上)


    函数组合

    先介绍一个概念,函数组合:函数组合是函数式编程中非常重要的思想,它的实现的思路也没有特别复杂。

    函数组合的两种形式(JavaScript函数式编程之函数组合函数compose和pipe的实现)

    有两种函数组合的方式,一种是pipe,另一种是compose。前者从左向右组合函数,后者方向相反。
    下面就是一个最简单的可以组合两个函数的compose

    let compose = (f, g) => (...args) => f(g(...args));
    

    在实际应用中,只能组合两个函数的组合函数显然不能满足要求,我们需要可以组合任意个函数的组合函数。下面提供两种思路。

    两种方法一种是递归,一种是循环,其实都是一样的。具体的思路就是,先写一个组合可以两个函数的compose2,用compose2先把传进来的末尾的两个函数组合了,返回一个函数func,然后再compose2把func和传进来的下一个函数组合起来,以此类推。

    循环的方法

    let compose2 = (f, g) => (...args) => f(g(...args));
    let compose = (...funcArgs) => (...args) => {
    let funced = funcArgs[funcArgs.length - 1];
    for (let i = funcArgs.length - 2; i >= 0; i--) {
        if (i === 0) {
        return compose2(funcArgs[i], funced)(...args);
        }
        funced = compose2(funcArgs[i], funced);
    }
    }
    
    // 与compose组合方向相反的函数组合函数
    let pipe = (...funcArgs) => compose(...funcArgs.reverse());
    

    递归的方法

    let compose2 = (f, g) => (...args) => f(g(...args));
    let compose = (...funcArgs) => (...args) => {
    let [...funcArgsCopy] = funcArgs;
    let callSelf = func => {
        if (funcArgsCopy.length === 0) return func;
        let funced = compose2(funcArgsCopy.pop(), func);
        return callSelf(funced);
    }
    return callSelf(funcArgsCopy.pop())(...args);
    }
    
    let pipe = (...funcArgs) => compose(...funcArgs.reverse());
    

    更简单的思路

    上面的思路还是有点麻烦,其实不用纠结在组合,直接把前一个函数的处理参数之后的返回值传给下一个函数就可以了。

    循环的方法

    let compose = (...funcArgs) => (...args) => {
        for (let i = funcArgs.length - 1; i >= 0; i--) {
        args = i === funcArgs.length - 1 ? funcArgs[i](...args) : funcArgs[i](args);
        }
        return args;
    }
    
    let pipe = (...funcArgs) => compose(...funcArgs.reverse());
    

    递归的方法

    let compose = (...funcArgs) => (...args) => {
        let [...funcArgsCopy] = funcArgs;
        let funced = (...func) => {
        if (funcArgsCopy.length === 0) return func[0];
        func = funcArgsCopy.pop()(...func);
        return funced(func);
        }
        return funced(...args);
    }
    
    let pipe = (...funcArgs) => compose(...funcArgs.reverse());
    

    然后我们来看一下webpack采用的组合方式

    webpack的加载从右往左进行

    其实为啥是从右往左,而不从左往右,只是Webpack选择了compose方式,而不是pipe的方式而已,在技术上实现从左往右也不会有难度

    在Uninx有pipeline的概念,平时应该也有接触,比如 ps aux | grep node,这些都是从左往右的。
    但是在函数式编程中有组合的概念,我们数学中常见的f(g(x)),在函数式编程一般的实现方式是从右往左

    const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
    const add1 = n => n + 1; //加1
    const double = n => n * 2; // 乘2
    const add1ThenDouble = compose(
    double,
    add1
    );
    add1ThenDouble(2); // 6
    // ((2 + 1 = 3) * 2 = 6) 
    

    这里可以看到我们先执行的加1,然后执行的double,在compose中是采用reduceRight,所以我们传入参数的顺序编程了先传入double,后传入add1

    那么其实也可以实现从左往右

    ———————————————————————————————————————————————

    参考文献:
    JavaScript函数式编程之函数组合函数compose和pipe的实现


    作者:小杺
    链接:https://www.jianshu.com/p/5d91f44358db
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
    备份还原工具—ghost
    太多的if,太多的痛苦
    C#中使用GUID
    WinForm开发中,将Excel文件导入到DataGridView中时,获取Excel中所有表格的名称。
    使用ASP调用C#写的COM+组件
    COM+ and the .NET Framework 虽是英文但比较全面
    在C#中使用COM+实现事务控制
    COM+ and the .NET Framework
    管理员ID过期,无人能够管理Domino服务器
  • 原文地址:https://www.cnblogs.com/ygunoil/p/13130858.html
Copyright © 2020-2023  润新知