原文:what-is-my-statejavascript
閱讀前須知前端
lens
和 atom
等。在我給出個人口味前,下面幾個矛盾,你會怎麼選擇?java
Most papers in computer science describe how their author learned what someone else already knew. — Peter Landingit
在讚美 Calmm 以前,咱們須要達成一些共識github
但願我們能從一個嶄新的角度討論 state ?算法
值、索引和時間相互交織,索引和時間尤爲複雜。typescript
key
通常的語言 (好比 js)對 state 這種數據基本都不作原生支持。編程
這體如今,在這些語言中:框架
這個說法對應於首類元素 first-class
,它ide
沒法(隨着時間)響應變化
let x = 1 // 建立了一個可變的 state let y = 2 let sum = x + y // 獲取了 state 的快照 snapshot,值爲 3 x = 3 sum // 值仍是 3,sum 沒法觀察 x 賦值後的值,隨之變化值爲 5
state 不是語言中的 first-class
元素
function foo() { let x = 1 // 建立可變的 state bar(x) // 沒法將 state 做爲參數傳遞,只能傳遞值,即 1 x = 2 // 修改了 state ,但這對於函數 bar 來講是不可知的 return x // 也沒法將 state 做爲返回,只能返回值,即 2 }
若是你瞭解 js ,知道變量區分值類型和引用類型、形參實參的分別,那麼就不會以爲上面的代碼有任何奇怪的地方。甚至你會以爲若是 x 從新賦值後, sum 會隨之變化爲 五、對已經調用完畢的 bar 還能產生影響,那才太可怕了。
但其實上面的代碼,並非在挑戰這些東西。而是假設咱們建立的
x
都是一種名爲state
的首類元素,它應當能夠
- 做爲函數的參數或返回值進行傳遞,而不只僅只是傳遞其計算值,即知足其身爲 first-class 的特性
- 能夠被其它引用它的函數或對象觀察到它的變化
固然,目前 js 中並不存在這樣的首類元素。
neta
Make American Great Again
, 哈哈
咱們試試在 js 中模擬出 State
下文代碼都是 typescript
interface State<T> { get(): T; set(value: T): void; }
咱們已經說過首類元素的特性了,能夠做爲函數的參數和返回值傳遞。
class Atom { constructor(value) { this.value = value } get() { return this.value } set(value) { this.value = value } }
如今在組件中,咱們就能夠聲明一個 state 來做爲參數了。
Observable state
class Atom { constructor(value) { this.value = value this.observers = [] } get() { return this.value } set(value) { this.value = value this.observers.forEach(observer => observer(value)) } subscribe(observer) { observer(this.get()) this.observers.push(observer) } }
state 能獨立於時間變化了(Independence from time)
decomposable
class LensedAtom { constructor({getter, setter}, source) { this.getter = getter this.setter = setter this.source = source } get() { return this.getter(this.source.get()) } set(value) { this.source.set(this.setter(value, this.source.get())) } }
把 store state 做爲一個總體,而其分片的元素做爲組件的 state
class PairAtom { constructor([lhs, rhs]) { this.lhs = lhs this.rhs = rhs } get() { return [this.lhs.get(), this.rhs.get()] } set([lhs, rhs]) { this.lhs.set(lhs) this.rhs.set(rhs) } }
通常咱們認爲 stream 是無狀態的,可是請看:
merge
+ scan
引入了局部狀態不過,從好的方便來講:
可使得依賴更精確:能夠方便地觀察「是什麼觸發了這個 stream ?」。
是的,在咱們的方案裏,任何人獲得了一個 state 的分片,均可以修改它。
可是在 calmm 中,咱們已經