今天,關於 JavaScript 中安全賦值運算子 (?=) 的新提案引起了熱烈討論。我喜歡 JavaScript 隨著時間的推移而不斷改進,但這也是我最近在某些情況下遇到的問題。我應該將一個快速範例實作作為函數,對吧?
如果您還沒有閱讀該提案,以下是其建議:
const [error, value] ?= maybeThrows();
新的 ?= 運算子相當於在 try/catch 區塊中呼叫賦值的右側,傳回一個陣列。如果在賦值中拋出了某些東西,則傳回數組的第一個值將是一個錯誤,如果沒有拋出任何東西,第二個值將是賦值的結果。
我經常遇到在賦值和 try/catch 區塊周圍感覺非常醜陋的程式碼。像這樣的事情:
let errorMsg; try { maybeThrow(); } catch (e) { errorMsg = "An error message"; }
要使用 const 存取 try/catch 區塊之外的 errorMsg,或讓您必須在區塊之外定義它。
這裡最簡單的情況是處理非非同步函數。我能夠振作起來
一些測試案例和一個名為 tryCatch 的函數很快就會出現:
function tryCatch(fn, ...args) { try { return [undefined, fn.apply(null, args)] } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws));
tryCatch 使用包含在 try/catch 區塊中的給定參數來呼叫函數。如果函數內部沒有拋出任何異常,它會適當地傳回 [undefined, result],如果確實拋出異常,它會適當地傳回 [error, undefined]。
請注意,如果您還沒有準備好呼叫的函數,您也可以將匿名函數與 tryCatch 一起使用。
console.log(tryCatch(() => { throw new Error("It threw"); }));
非同步函數變得有點棘手。我最初的一個想法是寫
一個完全非同步的版本,可能稱為 asyncTryCatch,但是其中的挑戰在哪裡。這是完全沒有意義的探索!以下是適用於非同步和非非同步函數的 tryCatch 實作:
function tryCatch(fn, ...args) { try { const result = fn.apply(null, args); if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); } return [undefined, result]; } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } async function asyncSum(first, second) { return first + second; } async function asyncThrows() { throw new Error("It throws async"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws)); // returns a promise resolving to value // prints [ undefined, 3 ] console.log(await tryCatch(asyncSum, 1, 2)); // returns a promise resolving to error // prints [ Error: 'It throws async', undefined ] console.log(await tryCatch(asyncThrows));
它看起來很像原始版本,但有一些基於 Promise 的程式碼
為了更好的措施而投入。透過此實現,您可以在呼叫非非同步函數時呼叫 tryCatch,然後在呼叫非同步函數時呼叫 wait tryCatch。
讓我們來看看 Promise 位元:
if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); }
if (result.then) 檢查給定函數(使用 apply 呼叫)是否回傳 Promise。如果確實如此,我們需要自己回傳一個 Promise。
如果沒有拋出任何異常,呼叫 result.then(v =>resolve([undefined, v])) 會導致 Promise 解析為給定函數傳回的值。
.catch(e =>resolve([e, undefined])) 有點棘手。我最初寫的
它為 .catch(e =>reject([e, undefined])),但這會導致未捕獲的錯誤
脫離 tryCatch。我們需要在這裡解決,因為我們要回傳一個
數組,不會拋出錯誤。
我經常遇到需要嘗試/抓住但感覺像是
的情況
明確的 try/catch 區塊會佔用大量空間,對於範圍分配來說很煩人。我不確定是否會使用它,但這是一個有趣的小探索。
以上是安全分配的詳細內容。更多資訊請關注PHP中文網其他相關文章!