1 of 26

簡約的軟體開發思維 16~17

前端讀書會/上德/2025-10-3

B L U E P L A N E T

2 of 26

章節

16. 多條時間線共享資源

17. 協調時間線

2

B L U E P L A N E T

3 of 26

復習

  • 今日大多數的軟體開發皆採分散式系統,掌握軟體如何隨時間變化是困難且重要的當務之急
  • FP 程式設計師的偏好:Data > Calculations > Actions
  • 在 FP 的語言裡,隱性輸入與輸出即是 side effects
  • 本書從15章開始用時間線圖 (timeline diagram) 來表示程式在時間線上的 Actions 序列

3

B L U E P L A N E T

4 of 26

Chapter 16. 多條時間線共享資源

4

B L U E P L A N E T

5 of 26

改善時間線五個原則

第15章13節已介紹改善時間線五個原則:

  1. 時間線數量越少越好
  2. 時間線上的步驟越少越好
  3. 共享資源越少越好
  4. 協調有共享資源的時間線
  5. 更改程式的時間模型

5

第16章

B L U E P L A N E T

6 of 26

隱性及顯性的時間模型

  • 程式語言自帶的時間模型是看不到、也無法直接修改的,故此處將其稱為「隱性」
  • 我們自行建立的時間模型則透過可自由操作、更改的 concurrency primitives 實現,因此為顯示「顯性」

6

B L U E P L A N E T

7 of 26

concurrency primitives

  • 用來處理併發 (concurrency) 操作的基本工具或機制 (primitive)
  • 將原本是「隱性」的時間模型轉換成「顯性」的時間模型
  • 本書 16 及 17 章皆是在實作 concurrency primitives
  • 我個人補充:本書是為了示範所以僅使用最基礎的程式語言來實作,實際上 Javascript 內建的 Promise 物件就是很好的工具,另外 RxJS 也是一個更進階的第三方函式庫。

7

B L U E P L A N E T

8 of 26

「放入購物車」程式仍可能出錯

  • Actions 之間有共享資源,因此順序就很影響到結果,程式運作有可能出錯。
  • 透過檢查三種潛在順序,找出錯誤順序的可能性

8

B L U E P L A N E T

9 of 26

在 Javascript 中自行建立佇列

必須確保順序的項目交由佇列處理器執行

9

B L U E P L A N E T

10 of 26

「放入購物車」程式 - 修改前

10

B L U E P L A N E T

11 of 26

「放入購物車」程式 - 放入佇列 (Queue)

11

B L U E P L A N E T

12 of 26

用 closure 做成可重覆使用的 Queue(worker)

12

修改前

B L U E P L A N E T

13 of 26

Chapter 17. 協調時間線

13

B L U E P L A N E T

14 of 26

改善時間線五個原則

第15章13節已介紹改善時間線五個原則:

  • 時間線數量越少越好
  • 時間線上的步驟越少越好
  • 共享資源越少越好
  • 協調有共享資源的時間線
  • 更改程式的時間模型

14

第17章

B L U E P L A N E T

15 of 26

讓兩個 ajax 同時執行後出現的 bug

15

B L U E P L A N E T

16 of 26

畫出時間線釐清問題

繪製時間線圖三大步驟:

  1. 辨識 Actions
  2. 將 Actions 畫在時間線上
  3. 簡化時間線圖

16

B L U E P L A N E T

17 of 26

辨識 Actions

17

B L U E P L A N E T

18 of 26

將 Actions 畫在時間線上

18

B L U E P L A N E T

19 of 26

簡化時間線圖

19

B L U E P L A N E T

20 of 26

等待兩個平行處理的回呼

20

B L U E P L A N E T

21 of 26

Cut()

  • 實作可重複使用的 concurrency primitives,使多條結束順序不固定的時間線能夠相互等待(至全部完成為止),避免程式進入「競態條件」(race condition)
  • 在多執行緒的程式語言中可使用「原子更新」(atomic update)機制

21

B L U E P L A N E T

22 of 26

「放入購物車」實作 Cut()

22

B L U E P L A N E T

23 of 26

JustOnce()

  • 修改 Cut() 函式,變成只執行一次的 concurrency primitives

23

B L U E P L A N E T

24 of 26

小結

24

B L U E P L A N E T

25 of 26

Recap

  • 非同步的時間模型是「隱性」的,透過 concurrency primitive 可以將時間模型轉換成「顯性」的
  • 畫出時間線圖、並透過檢查三種潛在順序(同時發生、左側優先、右側優先),找出錯誤順序的可能性
  • 第 16 章中,時間線上有共享資源,因此順序會影響結果造成 bug,透過自製的 Queue 控制順序
  • 第 17章中,多個時間線的順序會影響結果造成 bug,透過 Cut() 來互相等待時間線

25

B L U E P L A N E T

26 of 26

Thanks

26

B L U E P L A N E T