好用的 JavaScript Library 使用筆記(1):Lodash — flow
_.flow() 是 Lodash 提供的一個函數組合方法,類似 chain 的概念,可以將多個函數串聯起來,形成一個新的函數。這個新函數會按照從左到右的順序執行傳入的函數,前一個函數的輸出會成為下一個函數的輸入。
實際應用場景:購物車結算
讓我們以購物車結算為例,比較傳統寫法與使用 flow 的差異。假設我們已經有以下幾個購物車結算時需要用到的函式了:
// 步驟 1: 計算商品總價
function calculateSubtotal(cart) {
// ...
}
// 步驟 2: 處理折扣
function applyDiscounts(subtotal, user) {
// ...
}
// 步驟 3: 處理折價券
function applyCoupon(afterDiscount, coupon) {
// ...
}
// 步驟 4: 處理點數折抵
function redeemPoints(afterCoupon, userPoints) {
// ...
}
// 步驟 5: 計算運費
function calculateShipping(finalAmount) {
// ...
}傳統寫法(不使用 Flow)
function processCheckout(cart) {
const subtotal = calculateSubtotal(cart);
const discount = applyDiscounts(subtotal, cart.user);
const afterDiscount = subtotal - discount;
const couponDiscount = applyCoupon(afterDiscount, cart.coupon);
const afterCoupon = afterDiscount - couponDiscount;
const pointsUsed = redeemPoints(afterCoupon, cart.user.points);
const finalAmount = afterCoupon - pointsUsed;
const remainingPoints = cart.user.points - pointsUsed;
const shippingFee = calculateShipping(finalAmount);
const totalAmount = finalAmount + shippingFee;
return {
...cart,
subtotal,
discount,
afterDiscount,
couponDiscount,
afterCoupon,
pointsUsed,
finalAmount,
remainingPoints,
shippingFee,
totalAmount
};
}使用 Flow 的優雅寫法
// 購物車結算處理函數
const processCheckout = _.flow([
calculateSubtotal,
applyDiscounts,
applyCoupon,
redeemPoints,
calculateShipping
]);是不是看起來簡單很多呢?
兩種寫法的比較
傳統寫法的問題:
- 所有邏輯都混在一個大函數裡
- 變數名容易重複或混淆
- 難以單獨測試某個步驟
- 修改某個步驟可能影響其他部分
- 可讀性較差,需要仔細閱讀才能理解流程
Flow 寫法的優勢:
- 每個步驟都是獨立的函數,職責清晰
- 函數名具有表達力,一眼就能看懂流程
- 容易單獨測試每個步驟
- 修改某個步驟不會影響其他部分
- 可重用性高,函數可以在其他地方使用
- 讀起來就像在描述業務流程
Flow vs FlowRight
Lodash 還提供了 flowRight 方法,它與 flow 的區別在於執行順序:
// flow: 從左到右執行
const leftToRight = _.flow([addOne, multiplyByTwo]);
console.log(leftToRight(3)); // (3 + 1) * 2 = 8
// flowRight: 從右到左執行
const rightToLeft = _.flowRight([addOne, multiplyByTwo]);
console.log(rightToLeft(3)); // (3 * 2) + 1 = 7