
今天,關於 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中文網其他相關文章!