如下代码会用到函数组合函数compose,只要知道compose是干什么的就足够了,若是好奇具体的实现,能够看《JavaScript函数式编程之函数组合函数compose和pipe的实现》javascript
在写命令式的代码时,条件判断是常常使用的,常常会有以下类型的需求html
if (isTrue) { doSomething(); } else { return; }
好比表单验证java
if (!validate1()) return; if (!validate2()) return; axios.post(...)
若是有一个验证没有经过,则中止运行,只有所有都经过才会发出请求,提交表单。ios
可当咱们进行函数式编程时,这样的方式会遇到困难,难点在于如何中止。用上面命令式的代码,return了什么,return到了哪里,咱们都不太须要关心。而在函数式编程中,数据在管道中流动,上一个函数的返回值会传给下一个函数,除非报错,事先写好的流程是停不下来的。这时,函数返回了什么,咱们是必定要关心的。git
一样的需求,用函数式的写法github
let postData = () => axios.post(...); let result = compose(postData, validate2, validate1);
咱们一样但愿有一个验证没有经过就马上中止运行,可这是没法实现的,即便你在validate1里面写了一个return;
,这也只不过是中止了validate1的运行,并且还返回了一个undefined
传给了validate2。express
那咱们应该怎么作?编程
它要返回,就让它返回,只要返回值在咱们的控制中,不用打断运行一样也能够达到目的。axios
let security = fn => val => val === null || val === undefined ? null : fn(val);
咱们就能够用一个这样的函数来作安全验证,若是出现了验证失败,发现有空值,就返回一个null,若是正确就正常运行。数组
因此,以前的代码就能够这样改写,把可能会出错的地方全都包起来
let postData = () => axios.post(...); let result = compose(security(postData), security(validate2), security(validate1));
首先传给validate1的值,若是是空,则返回空给下一步,下一步一样有security的安全验证,接到空值往下传递。
看到这里,是否是感受这种思路有点熟悉?
咱们在用express写路由的时候,一般会这样写
try { doSomething(); } catch(err) { next(err); }
这个security方法与next(err)
就很是类似。
在写路由的时候,会有一个路由写在全部路由的最后,专门用来处理错误,借用这个思路,咱们一样也能够在函数组合时根据本身的须要在方程的最后作一些保底的操做,例如
let handleError = x => { if (!x) alert("errorMsg"); }; let result = compose(handleError, security(postData), security(validate2), security(validate1));
参考资料:
我在github
https://github.com/zhuanyongx...