理解 TypeScript 中的 “using” 關(guān)鍵詞
using 關(guān)鍵詞用于代替 const 和let,用于定義一個(gè)可釋放的對(duì)象,即一個(gè)在使用后可以自我清理的對(duì)象。
然而,這個(gè)關(guān)鍵詞源自 C#,那么 TypeScript 只是復(fù)制 C# 嗎?
并不是,TypeScript 只是從 C# 中挑選出最優(yōu)秀的特性,以提升整體開(kāi)發(fā)者體驗(yàn)。
今天解釋 using 關(guān)鍵詞在 TypeScript 中的工作原理,以及一個(gè)適用于 using 關(guān)鍵詞的常見(jiàn)使用場(chǎng)景。
工作原理
using 關(guān)鍵詞可以像 const 和 let 一樣使用。
// 注意:必須賦值某個(gè)值或返回一個(gè)值的函數(shù)。
using x = getX();
雖然這種賦值是可能的,但 using 關(guān)鍵詞應(yīng)該僅用于:
- 使用 Symbol.dispose 關(guān)鍵詞的對(duì)象。
- 返回使用 Symbol.dispose 關(guān)鍵詞的對(duì)象的函數(shù)。
- 否則請(qǐng)使用 const 或 let。
Symbol.dispose 是 TypeScript 中的一個(gè)特殊函數(shù),用于將一個(gè)對(duì)象標(biāo)記為“資源”,即一個(gè)可釋放的對(duì)象。
以下是一個(gè) TypeScript 中的“資源”示例:
// 使用 Symbol.dispose 標(biāo)記為可釋放的對(duì)象
const disposableObject = {
[Symbol.dispose]: () => {
console.log("Dispose of me!");
},
};
// 將對(duì)象用作資源
using resource = disposableObject;
我們可以通過(guò) await using 擴(kuò)展這一概念,這允許我們通過(guò)Symbol.asyncDispose函數(shù)異步釋放資源:
const getResource = () => ({
[Symbol.asyncDispose]: async () => {
await someAsyncFunc();
},
});
{
await using resource = getResource();
}
常見(jiàn)使用場(chǎng)景 —— 數(shù)據(jù)庫(kù)連接
數(shù)據(jù)庫(kù)連接可能是 using 的最常見(jiàn)使用場(chǎng)景。
原因很簡(jiǎn)單,你不需要在代碼中手動(dòng)關(guān)閉數(shù)據(jù)庫(kù)連接,讓 Symbol.asyncDispose 函數(shù)為你處理這個(gè)問(wèn)題。
以下是 TotalTypeScript 中的一些代碼片段,完美展示了這一點(diǎn)。
不使用 using:?
const connection = await getDb();
try {
// 使用連接進(jìn)行操作
} finally {
await connection.close();
}
使用 using:?
const getConnection = async () => {
const connection = await getDb();
return {
connection,
[Symbol.asyncDispose]: async () => {
await connection.close();
},
};
};
{
await using db = await getConnection();
// 使用 db.connection 進(jìn)行操作
} // 自動(dòng)關(guān)閉!
想象一下,現(xiàn)在你可以擁有的這種安心感。
數(shù)據(jù)庫(kù)連接的關(guān)閉現(xiàn)在通過(guò) Symbol.asyncDispose 和 using 關(guān)鍵詞自動(dòng)且負(fù)責(zé)任地處理。
結(jié)論
using 關(guān)鍵詞用于定義“資源”,這些資源是包含 Symbol.dispose 函數(shù)的可釋放對(duì)象。
using 關(guān)鍵詞的加入將消除大量意外的 bug,并將開(kāi)發(fā)者體驗(yàn)提升十倍。