Redux源碼分析之compose


 Redux源碼分析之基本概念 

Redux源碼分析之createStore 

Redux源碼分析之bindActionCreators 

Redux源碼分析之combineReducers 

Redux源碼分析之compose

Redux源碼分析之applyMiddleware 

   

 解讀之前先了准備一下基本知識

   形式為...變量名,用於獲取函數的多余參數 ,該變量將多余的參數放入數組中, 只能是參數的最后一個。

   擴展運算符(spread)是三個點(...)。它好比 rest 參數的逆運算,將一個數組轉為用逗號分隔的參數序列。      

var fun1 = (...args) => console.log(...args)
 fun1(1,'Good')
// 結果輸出 1, Good

 

 這是一個很重要的函數 compose, 其作用紅色部分表達的很清楚。

其作用是把一系列的函數,組裝生成一個新的函數,並且從后到前,后面參數的執行結果作為其前一個的參數。

/**
 * Composes single-argument functions from right to left. The rightmost
 * function can take multiple arguments as it provides the signature for
 * the resulting composite function.
 *
 * @param {...Function} funcs The functions to compose.
 * @returns {Function} A function obtained by composing the argument functions
 * from right to left. For example, compose(f, g, h) is identical to doing
 * (...args) => f(g(h(...args))).
 */

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }      

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

還是先來看一個簡單的例子,結果上確實是如我們期望的。

var fn1 = val => 'fn1-' + val
var fn2 = val => 'fn2-' + val 
var fn3 = val => 'fn3-' + val 

compose(fn1,fn2,fn3)('測試')

輸出結果: fn1-fn2-fn3-測試

 我們回頭看看最核心的一行代碼。 

  return funcs.reduce((a, b) => (...args) => a(b(...args)))

  我們一步一步分解一下, func3 初始化的值為 funcs = [fn1,fn2,fn3], reduce執行

   第一步時 

  a = fn1

  b = fn2 

       a(b(...args)) = fn1(fn2(...args))

  (...args) => a(b(...args))   = (...args) = > fn1(fn2(...args))

  第二步時

      a =  (...ag) = > fn1(fn2(...ag))  // 避免和后面混淆,rest參數名修改為  ag

      b = fn3

      a(b(...args)) = a( fn3(...args) )  = fn1(fn2(    fn3(...args)   ))  // 這一步是關鍵,b(...args)執行后作為a函數的入參,也就是 ...ag = fn3(...args)

   (...args) => a(b(...args))   = (...args) = > fn1(fn2(fn3(...args))) 

 

   所以最后返回的就是這樣的一個函數  (...args) = > fn1(fn2(fn3(...args))) 

   再多函數,也是以此類推。  

 

引用:

redux middleware 詳解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM