一、業務場景
衆所周知,在客戶端中,表單是一個相當重要的內容。隨着技術的發展,在提交表單數據的時候,某些表單驗證環節會放在前端進行。因此,我們無可避免的要寫一堆 if 來處理,同時大多數的時候,如果需要提醒某些錯誤信息時,需要加入 else 以及 else if 來控制,當然也可以使用 retrun。不過隨着表單越來越複雜,表單項之間的關聯越來越複雜的時候,看着一屏都放不下的判斷嵌套,心中是萬千草泥馬奔騰而過。
二、與 promise 的結合
promise 的出現主要是爲了解決複雜的回調嵌套,因此在這裏也是借用了這個特點,解決我們的痛點。代碼見下:
function validate (scb = () => {}, ecb= () => {}) { return new Promise((resolve, reject) => { // area 1 if (...) reject('error message 1'); if (...) reject('error message 2'); if (...) reject('error message 3'); if (...) reject('error message 4'); ... // area 2 resolve(); }).then((result) => { // area 3 scb(); }).catch((err) => { // area 4 console.error(err); yourToastFunc(err); ecb(); }); }
代碼中 area 1 是主要的邏輯判斷區, area 2 執行時表示 area 1 中的驗證全通過, area 3 則是全通過之後的成功回調函數(scb => successCallback 縮寫, ecb 同),相反 area 4 是未通過之後的處理區域。這段主要是利用 reject 阻斷後續代碼執行的特性,直接捕獲當前錯誤的地方從而確定是何條件未通過以及對應的提示語,從而提高後續的定位速度。
三、一些思考
這段代碼本身並沒有改變多少思考範式,本身也依賴 area 1 中的邏輯判斷語句的編寫,優點是在條件判斷的下一步做了一點統合,不必再每一個分支內重複地寫 return or toast。簡單而言,就是用 reject 儘可能代替了 else。
同時,因爲 area 1 中的需要編寫判斷的原因,這裏也是耦合度較高的地方,從這方面講,是可以後續改進的地方。不過,需要掌握好平衡。
當然,後續升級的方向也可以是像 element-ui 的 form 那樣,傳入對象,傳入自定義的驗證器等等,同時這裏又要考慮作用域(用於某些表單聯動時上下文中的變量獲取)等等問題。
總之,沒有完美的解決方案。事物的發展是螺旋式前進的,實事求是,根據不同的實際抽象出不同的核心需求,然後選擇才能總結出相應的最合理的解決辦法。