程式碼請參考 D15/asynchronous
今天講的程式碼主要會在這裡
src\app\edit\courses\all\components\add-course-form\users\feature\add-user.ts
範圍包含 步驟1 與 步驟2
當我們輸入完畢,有兩個不同的事件會觸發新增使用者的流程
Enter
Add
按鈕如果是鍵盤事件,我們可以藉由檢查 event.key
是否為 Enter
來判斷是否觸發後續工作流程,如果是滑鼠事件,則必定觸發後續工作流程。
所以我們可以把難以判讀的 event 轉換成兩個 literal type
const parseEvent = (event: unknown): 'Nothing' | 'AddUserEvent' =>
pipe(
Match.value(event),
Match.when({ key: Match.string }, ({ key }) =>
pipe(
Match.value(key),
Match.when('Enter', () => 'AddUserEvent' as const),
Match.orElse(() => 'Nothing' as const)
)
),
Match.orElse(() => 'AddUserEvent' as const)
)
這種寫法不像 boolean
等等邏輯表示式,利用簡單的 literal type
,就能充分表達語意,提高可讀性。
export const addUser =
(event: unknown) =>
(field: UsersField): Effect.Effect<never, 'Nothing', UsersField> =>
pipe(
Match.value(parseEvent(event)),
Match.when('Nothing', () => {/* do nothing */}),
Match.when('AddUserEvent', () => {/* run subsequence workflow */}),
Match.exhaustive
)
所有網路通訊都會有延遲,導致我們必須進行異步處理,而且通訊過程有可能出錯,同時還可能必須存在某些外部依賴才可以進行連線。
以上三個面向相關的邏輯,雖然和程式主要運行流程不一定有直接關係,卻非常繁瑣,經常占用工程師大量時間處理,因此我們會藉由 effect
來幫助我們解決以上問題。
關於什麼是
資料型別盒子
,請參考 D08 - 資料型別盒子
Effect
盒子由三種 generic type
組成
type Effect<Requirements, Error, Value> = (
context: Context<Requirements>
) => Error | Value
Requirements 有時候用 R
表示,其實就跟我們在 D12/設計依賴注入 中談到的內容具有很相似的設計思想,我們可以透過介面先假裝有某項資源或服務存在,再在程式碼的執行階段使用它,不過暫時我們還不會用到它。
Error 通常用 E
表示,跟 D07/軌道導向設計 中提到的 Left
是一樣的概念,通常代表錯誤或異常,也代表會離開正常的工作流程。
Value 有時候會用 A
表示,跟 D07/軌道驅動設計 中提到的 Right
是一樣的概念,通常代表成功執行將會產生的結果,也代表會繼續走在正常的工作流程上。
要如何得到一個 effect 盒子呢? 其中一個方法是使用 Effect.tryPromise
const getUser = (name: string):Effect.Effect<never, RequestError, AxiosResponse> =>
pipe(
Effect.tryPromise({
try: () => axios.get(`/api/v1/users/${name}`).then((res) => res.data),
catch: (error) => requestErrorOf(error),
}),
)
使用它時必須提供兩個參數
()=>Promise<Value>
代表可能發生錯誤的異步操作(error: unkown)=>Error
如果發生錯誤,允許你對這個未知的錯誤做處理,轉換成型別上比較有意義的錯誤。當提供完這兩個參數後我們就會得到 Effect.Effect<never, RequestError, Any>
never
表示它沒有外部依賴RequestError
表示它可能會發生請求錯誤,而請求錯誤由 UnexpectedRequestError
和NotFoundError
組成Any
表示我們將收到一個 任意型別
的回應當我們看到 any
請不要開心,而是要覺得驚恐,要想盡辦法把它扼殺在搖籃之中 !!!
明天我會跟大家分享,如何把 any
變成可靠的、經過驗證的、已知的型別,敬請期待 !