在 Promise Chain 中使用 cond()
con()
若在 pipe()
中以 Function Pipeline 使用沒有問題,但若要搭配 Promise Chain 該如何使用呢 ?
失くすものさえない今が強くなるチャンスよ
con()
若在 pipe()
中以 Function Pipeline 使用沒有問題,但若要搭配 Promise Chain 該如何使用呢 ?
when()
若在 pipe()
中以 Function Pipeline 使用沒有問題,但若要搭配 Promise Chain 該如何使用呢 ?
由於 Promise 的 then()
具有 chain()
特性,實務上使用 Nested Promise 機會不大,大都可使用 Promise Chain 解決,若萬一使用 Nested Promise 時,該如何裡 Rejected Promise 呢 ?
converge()
允許我們輸入單一 Argument 時,先同時使用多個 Branching Function 處理成多 Argument 再傳入 Converging Function,事實上也可使用 lift()
實踐。
若只想取 String 前幾個 Char,Ramda 提供了 take()
。
若只想取 Array 前幾筆資料,Ramda 提供了 take()
。
從 API 取得 Object Array 時,常會遇到 Package 雖然也接受 Object Array,但 Property 與 API 回傳不同,此時可使用 map()
+ applySpec()
加以改變 Property。
將結果依日期排序且最新日期在第一筆,也是實務上常見需求,由於 Date 特性,排序時並不像 Number、String 那樣簡單,須自行實作 Comparator Function。
Ramda 的 sort()
與 sortBy()
都只能針對單一排序條件;若要多排序條件只能使用 sortWith()
。
對於一般排序,sort()
就很好用,若要先根據 Function 運算後再升冪排序,就要使用 sortBy()
。
Ramda 的 sort()
與 ECMAScript 內建的 Array.prototype.sort()
非常類似,都需自行提供 Comparator Function,唯 sort()
是無 Side Effect 版本。
實務上有時會想 Button 的 Border 取消,可設定 Button 的 border-color
與 border-style
,雖然都會看不到 Border,但兩者底層還是有些差異。
寫程式免不了要使用判斷邏輯,若要實現 switch
根據不同條件執行不同 function,Ramda 提供了 cond()
。
FP 不單只能用在 Array 與 Object 而已,事實上原本 if else
statement 也能以 ifElse()
取代,連多層 if else 也能以 ifElse()
實現。
Side Effect 在實務上不可避免,若同時要對相同 Value 執行多次 Side Effect 時,標準做法是使用 tap()
,可使用 seq()
更精簡。
若第一個 Function 結果為 Falsy Value 則回傳第一個 Function,否則回傳第二個 Function,在 FP 稱為 AND Combinator,可使用 Ramda 的 both()
實現。
若第一個 Function 結果為 Truthy Value 則回傳第一個 Function,否則回傳第二個 Function,在 FP 稱為 OR Combinator,可使用 Ramda 的 either()
實現。
if else
在每個程式語言都有,但這是 Imperative 使用方式,會使得 Function Pipeline 中斷,事實上可使用 Function 加以重構。
若要從 Array 產生連續 n-tuple,可使用 aperture()
。
若要將兩個 Array 相減,Ramda 可使用 difference()
與 without()
,兩者差異只有 Argument 順序不同。
若要對兩個 Array 相減,且想自己提供比較條件,可使用 differenceWith()
處理, 尤其對 Object 比較的是 Value 而不是 Reference。
若要對兩個 Array 相減,可使用 difference()
處理, 尤其對 Object 比較的是 Value 而不是 Reference。
若想在 Array.prototype.map()
的 Callback 得知目前 Element 的 Index,其 Callback 的第二個參數就是 Index,但 Ramda 的 map()
並沒有提供此功能,可使用 addIndex()
加上 Index。
ECMAScript 的 Array.prototype
、String.prototype
、Object.prototype
… 都有很豐富 Instance Method 可用,唯這些 Method 都是以 OOP 形式提供,不方便 Function Pipeline,可使用 Ramda 的 invoker()
將其轉成 Free Function。
ECMAScript 提供了不少原生 Static Method,但我們也可使用 Ramd 的 bind()
將其轉成 Free Function 使其更符合 FP 風格。
Ramda 並沒有提供四捨五入到整數的 Function,但可藉由 bind()
將 ECMAScript 原生的 round()
從 Static Method 轉成 Free Function。
Ramda 並沒有提供四捨五入到小數點的 Function,但可藉由 invoker()
將 ECMAScript 原生的 toFixed()
從 Instance Method 轉成 Free Function。
實務上我們想取得 File Name,但所得 String 卻包含 Folder 名稱,此時我們該如何只取得 File Name 呢 ?
實務上很多資訊都來自於 String,但 API 要求的 Body 卻是 Object,所以由 String 轉成 Object 需求常常遇到,這該如何實現呢 ?
實務上常遇到在 Function Pipeline 中處理 Array,但結果卻是 Object,此時可用 zipObj()
加以轉換。
實務上常須判斷 String 是否以特定 String 開始,這種常見需求,該如何實現呢 ?
RxJS 提供了 pluck()
直接取得 Object 的 Property,若要取得部分 Property,RxJS 並沒有提供直接 Operator,此時可使用 RxJS 的 map()
+ Ramda 的 pick()
實現。
Front-end 兩大 Asynchronous 就是 DOM Event 與 API Request,實務上常將這兩個 Asynchronous 視為 Observable 一起處理,這導致了 Higher Order Observable 出現,RxJS 提供了 mergeMap()
、concatMap()
、switchMap()
與 exhaustMap()
處理,本文探討 switchMap()
。
RxJS 與 Ramda 同屬 Functional Library,RxJS 特色在於 Asynchronous 部分,而 Ramda 則在於 Synchronous,事實上 RxJS 與 Ramda 可搭配 Vue 一起使用。
若 API 遵循 RESTful 精神設計,常會第一個 API 僅回傳 id
,若要取得其值就要呼叫第二個 API,也就是所謂 N + 1 Query,RxJS 對這種常見需求有很漂亮寫法。
一般談到 Function Composition,直覺都會想到 pipe()
與 compose()
,事實上就廣義而言, map()
、useWith()
、 converge()
與 chain()
也算是。
使用 Function Pipeline 時,有時會想使用前兩個 Function 的回傳值,但因為橫跨在不同 Function 彼此看不到對方,此時可使用 Pair 將前一個 Function 回傳值包起來傳到下一個 Function。
對於一般需求,uniq()
即可勝任,但若需經過 Function 轉換後才比較,則要使用 uniqBy()
,自行傳入 Callback。
寫程式免不了要使用判斷邏輯,若只有 Predicate 為 false
才執行 Function,true
回傳原值,Ramda 提供了 unless()
。
寫程式免不了要使用判斷邏輯,若只有 Predicate 為 true
才執行 Function,false
回傳原值,Ramda 提供了 when()
。