使用ramdajs进行函数式编程遇到的实际问题

几个基础概念的作用

纯函数(pure function),柯里化(curry),组合(compose)。

纯函数的作用

  1. 输入确定输出。
  2. 可缓存。
    因为输入确定输出,可缓存历史的输入输出
    下次同样的输入,直接通过映射就得到输出。
  3. 易测试。

柯里化的作用

  1. 延迟执行。
  2. 生成受限函数。

组合的作用

  1. 易复用
    复用函数,比面向对象的继承顺手。
  2. 易修改
    改变组合,比面向对象的重写顺手。

参考

理解上述内容可参考JS函数式编程指南
下面是实际工作中所要解决的问题。

实际运用ramdajs编程遇到的问题

1. 异步

你可以使用PromiseramdajscomposeP来处理异步

2. 错误抛出

且看这个场景:函数a => 函数b => 函数c => 函数d
假设函数a输出了一个异常数据,你想直接忽略函数b,c,d的处理,返回这个异常数据。
示例代码如下:

var R = require('ramda');
var log = console.log.bind(this);

var setTimeout1 = R.curry(function( b ){
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      callback('正在setTimeout1中,传入参数为', b);
      try{
        aaa
      }
      catch(err){
        reject('拒绝');
      }
      
      resolve('进入setTimeout2');
    },1000);
  })
});

var setTimeout2 = R.curry(function( arg ){
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve('接受');
    },2000);
  });
});

var app1 = R.composeP(setTimeout2(log) ,setTimeout1(log));
var app2 = R.composeP( function(x){return 'app 2';} ,app1);

var result = app2("test")
.then(function(x){return 'test...end';})
.catch(function(error){log('error:', error)});

/*
控制台输出结果:
正在setTimeout1中,传入参数为 test
error: 拒绝
*/

3. 并行

示例代码如下

const R = require('ramda');

const setTimeout1 = function (value) {
  return new Promise(function (resolve, reject) {
    resolve(value);
  });
};

const setTimeout2 = function (value) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(value);
    }, 2000);
  });
};

const all = function () {
  return Promise.all([setTimeout1(10), setTimeout2(100)]);
};

const app = R.composeP(
  function (values) { console.log('arg1', values); },
  all
);
app();

推荐阅读更多精彩内容