如下代碼會用到函數組合函數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...