iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 8
1
Software Development

Functional Programming in JS系列 第 8

Buzz word 4 : Stateless

準確一點應該是 Stateless function,更語意一點就是 Avoid Shared State,因為一個系統中不太可能全部都是 Stateless 的,還是要有地方存這些狀態。

Stateless is any variable, object, or memory space that exists in a shared scope, or as the property of an object being passed between scopes.

shared scope 可以包含在 global scope 或是 function scope (恩,其實 JS 總共也才這兩個 scope)。

以前很習慣 Shared state (Stateful),不管是 global scope 裡的變數或增加/減少 object 裡的屬性。

// words = ['world', 'fp', 'to', 'welcome']
let keepers = []
 
for(let i in words) {
   if(words[i].length > 3) {
     keepers.push(words[i])
   }  // ['world', 'welcome']
}
// 程式大家一起 Share keepers 這個 Array 

Shared state 最大問題就是你必須很清楚每一行程式碼在做什麼,什麼時候做了什麼事變動了 state,並且要記憶 state 變成多少 。一但系統變複雜或是有多個工程師共同開發就必須花大量時間去弄懂程式碼在幹嘛 (崩潰狀)

// Stateful
const x = 4; 
x++; // x 變 5
// 省略 100 行...

x*2 // 完全不知道哪行改過 x,現在到底變成什麼
 

https://ithelp.ithome.com.tw/upload/images/20200908/20106426JMEtcqgfQ8.jpg
若還加上 promise 、setTimeout 的運算更難掌握處理 State 的先後次序 (就像上圖中 state 並不是獨立存在而是互相依賴在別的運算或函式中); 但若改成 FP 習慣的 Stateless function,你完全不用去記憶 state 到底是什麼,因為他只存在單一函數中,執行完 state 就被丟掉了

// Stateless
 _.filter(x => x.length > 3),  // 不用記憶 x 是什麼

另外一個缺點是 Share State 會有順序與執行次數問題

const x = {
  val: 2
};

const x1 = () => x.val += 1;

const x2 = () => x.val *= 2;

x2();
x1();

console.log(x.val); // 5

x2();
x1();
console.log(x.val); // 11

以上範例會發現執行次數影響結果,那改成 Shareless 呢

const x = {
  val: 2
};

const x1 = x => Object.assign({}, x, { val: x.val + 1});
const x2 = x => Object.assign({}, x, { val: x.val * 2});

console.log(x1(x2(x)).val); // 5

x2(x);
x1(x);
// 那順序改變呢
console.log(x1(x2(x)).val); // 5

就會發現不管執行幾次結果都還是一樣

這一篇比較簡短一點(我不會說出來,其實是文章庫存都被我用完了 orz),由範例可以看到 Share State 通常資料也會是 Immutable 的,然後 Immutable data 又容易產生無法預期的 Side Effect,這一些 Buzz Words 其實都是環環相扣的啊


參考文章

如有錯誤或需要改進的地方,拜託跟我說。
我會以最快速度修改,感謝您

上一篇
把 Mutable array/object 轉成 Immutable
下一篇
Buzz word 5 : Pure Function
系列文
Functional Programming in JS30

尚未有邦友留言

立即登入留言