首頁 >web前端 >js教程 >安全分配

安全分配

WBOY
WBOY原創
2024-09-10 14:30:15509瀏覽

Safe Assignment

今天,關於 JavaScript 中安全賦值運算子 (?=) 的新提案引起了熱烈討論。我喜歡 JavaScript 隨著時間的推移而不斷改進,但這也是我最近在某些情況下遇到的問題。我應該將一個快速範例實作作為函數,對吧?

如果您還沒有閱讀該提案,以下是其建議:

const [error, value] ?= maybeThrows();

新的 ?= 運算子相當於在 try/catch 區塊中呼叫賦值的右側,傳回一個陣列。如果在賦值中拋出了某些東西,則傳回數組的第一個值將是一個錯誤,如果沒有拋出任何東西,第二個值將是賦值的結果。

常見的 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn