美文网首页
浅解惰性函数链式调用

浅解惰性函数链式调用

作者: zdxhxh | 来源:发表于2019-11-26 22:04 被阅读0次

    函数链

    这里写一下lodash的函数链式调用

    我曾经在哪里看过类似的源码,但又忘记了 现在来模拟一下

    我们来看以下代码,实际上lodash这种函数调用,是在真正执行.value时,才会调用函数链上的方法

    _.chain(persons)
      .filter(s=> !_.isUndefined(s) && !_.isNull(s))
      .map(_.property('address.country'))   // 使用_.property抽取person对象的address.country属性,这是Ramda的R.viw()的Lodash对应版本
      .reduce(gatherStats,{})
      .values()         // 这里将对象创建成了可枚举的数组对象
      .sortBy('count')    
      .reverse()
      .first()
      .value()
    

    我想起来了,是在es6的proxy里面写了相关东西

    思考上述写法的难点在哪里?是当我.xxx时,要将这个函数存到一个队列中,在当执行.value时,才逐个调用函数链上的方法.

    es5的做法,面向对象,通过原型链既可以模拟这一效果

    function Chain(instance) { 
      if(this instanceof Chain) { 
        this.instance = instance 
        this.stack = [] 
      } else { 
        return new Chain(instance)
      }
    
    }
    
    Chain.prototype.value = function() {
      let result = this.stack.pop() 
      while(result) { 
        result()
        result = this.stack.pop()
      }
      return this.instance
    }
    
    const fnMap = { 
      filter : function(arr,fn) { 
        let temp = [],
            length = arr.length,
            index = -1 
        while(++index < length) { 
          if(fn(arr[index])) { 
            temp.push(arr[index])
          }
        }
        return temp 
      },
      map : function(arr,fn) { 
        let temp = [],
            length = arr.length,
            index = -1
        while(++index < length) { 
          temp.push(fn(arr[index]))
        }
        return temp 
      }
    }
    
    Object.keys(fnMap).forEach(key=> { 
      console.log(key)
      Chain.prototype[key] = function(fn) { 
        let self = this 
        this.stack.push(function() { 
          self.instance = fnMap[key](self.instance,fn)
        })
        return this
      }
    })
    
    console.log(Chain([1,2,3]).map(item=>item * 6).filter(item=>item!==6).value())  // logs [6,12,18]
    

    es6可以使用proxy做到可以点击这里看es6proxy

    const pipe = function(value) { 
      const fnStack = [],
      oproxy = new Proxy({},{
        get : function(target,key) { 
          if(key === 'get') { 
            return fnStack.reduce(function (val, fn) {
              return fn(val);
            },value);
          }
          fnStack.push(window[key]);
          return oproxy;
        }
      })
      return oproxy;
    }
    var double = n => n * 2;
    var pow    = n => n * n;
    var reverseInt = n => n.toString().split("").reverse().join("") | 0;
    
    pipe(3).double.pow.reverseInt.get; // 63
    

    相关文章

      网友评论

          本文标题:浅解惰性函数链式调用

          本文链接:https://www.haomeiwen.com/subject/xrxuwctx.html