Will it finally: 關於 try/catch 的一些細節

隨着async /await的出現,我最近發現本身在個人代碼中使用了更多try /catch /finally。但老實說,我終於用「finally」作了一點練習。當我去實際使用它時,我有點不肯定它的細節。因此我把幾個例子放在一塊兒。async

當你 throw 一個 catch

考慮你在一個catch塊跑出一個異常。在退出函數以前沒有什麼能夠捕獲你的throw。那「 finally」會運行嗎??函數

function example() {
  try {
    fail()
  }
  catch (e) {
    console.log("Will finally run?")
    throw e
  }
  finally {
    console.log("FINALLY RUNS!")
  }
  console.log("This shouldn't be called eh?")
}

 example()

控制檯結果日誌

Will finally run?
FINALLY RUNS!
Uncaught ReferenceError: fail is not defined
    at example (<anonymous>:3:5)
    at <anonymous>:15:2

finally運行,即便並無打印最後一個日誌語句!但它確實拋出了錯誤。code

你能夠看到finally有點特別;它容許你在拋出錯誤和離開函數之間運行,即便拋出catch塊。it

嘗試沒有捕獲(catch)

您是否知道若是您提供finally塊,您也不須要提供catch塊?你可能作到了,但值得一提!io

接下來的問題是:即便在try塊中沒有出錯,finally塊也會被調用嗎?console

function example() {
  try {
    console.log("Hakuna matata")
  }
  finally {
    console.log("What a wonderful phrase!")
  }
}

example()

控制檯結果function

[log] Hakuna matata
[log] What a wonderful phrase!

是的,即便沒有出錯也會調用finally。固然,當does出錯時,它也會被調用。call

這就是finally背後的想法 - 它可讓你處理這兩種狀況,正如你在這個例子中看到的那樣:異常

function example() {
  try {
    console.log("I shall try and fail");
fail();
}
  catch (e) {
    console.log("Then be caught");
}
  finally {
    console.log("And finally something?");
}
}

 example()

控制檯結果

[log] I shall try and fail
[log]Then be caught
[log] And finally something?

那若是return了? finally還會執行嗎?

因此最後讓你在異常發生時本身清理。可是何時什麼都不會出錯,你只是從函數中「返回」正常...在try塊中?

看看下面的例子。example()中的finally塊是否能夠運行after你已經命中了return語句?

function example() {
  try {
    console.log("I'm picking up my ball and going home.")
    return
  }
  finally {
    console.log('Finally?')
  }
}

example()

控制檯結果

[log] I'm picking up my ball and going home.
[log]Finally?

規則

try /catch /finally上的finally塊都將運行 - 即便你提早catch或'return`。

這就是它如此有用的緣由;不管發生什麼狀況,它都將運行,那麼這就是將,始終要運行的代碼的理想場所,好比容易出錯的IO的清理代碼。事實上,這就是本文的靈感來源。

相關文章
相關標籤/搜索