redux源碼解讀--compose源碼解析

compose源碼解析

compose模塊的代碼十分簡練,可是實現的做用倒是十分強大。redux爲什麼稱爲redux?有人說就是reduceflux的結合體,而reduce正是compose模塊的核心。git

compose模塊所實現的功能強大而簡單:從右到左,組合參數(函數)。因此,傳遞給compose方法的參數,必須都是函數類型的(這一點,在源碼中沒有判斷,多是由於這個模塊是redux內部使用的模塊,沒有對外暴露,因此不須要很強的校驗。)。例如:github

compose(f, g, h) ====> (...args) => f(g(h(...args)))

模塊的代碼很簡單,可是涉及到的內容卻很重要,下面一點一點的看。redux

reduce是什麼?數組

reducees5中的數組的一個方法,對累加器和數組中的每一個元素(從左到右)應用一個函數,將其減小爲單個值。函數簽名爲:函數

arr.reduce(callback[, initialValue])

callback是執行數組中每一個元素的函數,這個函數接收幾個參數:測試

  • accumulator:上一次callback調用的返回值,若是是第一次調用,則這個值就是initialValue。若是沒有提供initialValue則使用數組的第一個元素。
  • currentValue: 數組正在處理的元素
  • currentIndex: 數組正在處理的元素的當前的索引
  • array: 調用reduce方法的數組

綜上,reduce方法詳細的簽名就是:es5

arr.reduce(function (accumulator, currentValue, currentIndex, array) {}[, initialValue])

幾個小Demospa

  • 數組求和
[1,2,3,4,5].reduce((a, b) => a + b) // 15
  • 數組拉平
[[0, 1], [2, 3], [4, 5]].reduce((a, b) => {
  return a.concat(b);
}, []);  // [ 0, 1, 2, 3, 4, 5 ]

關於reduce詳細的文檔能夠參考Array.prototype.reduceprototype

明白了reduce是怎麼回事以後,咱們先來看一下compose有什麼神奇的效果:code

import compose from '../src/compose'

// function f
const f = (arg) => `函數f(${arg})` 

// function g
const g = (arg) => `函數g(${arg})`

// function h 最後一個函數能夠接受多個參數
const h = (...arg) => `函數h(${arg.join('_')})`

const r = compose(f, g, h)

console.log(typeof r) // function

console.log(r(1,2,3)) //函數f(函數g(函數h(1_2_3)))

從上面能夠的代碼能夠看出:compose的運行結果是一個函數,調用這個函數所傳遞的參數將會做爲compose最後一個參數的參數,從而像'洋蔥圈'似的,由內向外,逐步調用。

圖片描述

源碼

export default function compose(...funcs) {
  // funcs是一個保存着全部參數函數的數組
  // 若是沒有傳遞任何參數,就返回一個函數,這個函數是輸入什麼獲得什麼。
  if (funcs.length === 0) {
    return arg => arg
  }
  // 只傳遞一個參數的時候,就直接把這個函數返回
  if (funcs.length === 1) {
    return funcs[0]
  }
  // 返回組合函數
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

這就是對compose源碼的一個總體解讀,水平有限,歡迎拍磚。後續的源碼解讀和測試例子能夠關注:redux源碼解讀倉庫

相關文章
相關標籤/搜索