標題那串聽起來很恐怖,但其實並不是陌生的新問題。anti-pattern 是指常見但不太有效或有待優化的作法,而 promise constructor anti-pattern 就是「多餘使用 promise 建構式」這樣的問題,之所以會過多使用往往是因為忽略了 promise 本身靈活的特性。
例如這個問題中的程式碼:
function getStuffDone(param) {
return new Promise(function(resolve, reject) {
myPromiseFn(param+1)
.then(function(val) {
resolve(val);
}).catch(function(err) {
reject(err);
});
});
}
它的問題在於既然 myPromiseFn
會回傳 promise,外面就不需要再包一層 promise 建構式。另外也可以把鏈接寫在呼叫 getStuffDone
的同一層,所以可以改寫成這樣就好:
function getStuffDone(param) {
return myPromiseFn(param+1);
};
提出 promise constructor anti-pattern 的 Esailija 說,promise 的重點應該在於讓非同步程式碼能跟同步程式碼有一樣特性:可以在同一層撰寫、有共通的錯誤處理...等等,而不應該只是被當成比較好看的事件監聽器或 callback。除了多餘建構式,他還舉例另一種也是多餘寫法造成的問題,就是在 promise 中再包一層 callback-based 函式,等於還是在用原本不良的方式解決問題。
那如果這樣寫只是「醜」或「囉嗦」但程式可以運作,繼續用有關係嗎?根據 Stack Overflow 一個回答者的經驗,過半數這樣寫的程式碼都會漏掉內層 promise 的錯誤處理,也就是之所以會稱為 anti-pattern 重點就不在於當下有多少錯誤,而是在於它容易出錯 (error-prone)。
then(success, fail) anti-pattern 也很有趣,可以想像被建議不要這樣寫的人一定會很生氣說:文件上都這樣寫了為什麼不行!但即便都是正式的方法,還是有人討論和比較了一番。
第一次看到 anti-pattern 這個詞覺得很高興,原來那些「雖然不太好,但大家都這樣」的問題可以這樣表達,然後也有很多人整理問題細節。這頁有各領域常見的 anti-patterns,很多名稱很有畫面感,可以參考。