gpt4 book ai didi

typescript - TypeScript 中的 IDisposable/RAII?

转载 作者:行者123 更新时间:2023-12-04 13:46:15 26 4
gpt4 key购买 nike

在 TypeScript 中实现确定性清理的惯用方法是什么?换句话说,是否有等效于 C# 的 using (IDisposable)还是 C++ 的 RAII?

或者我应该坚持使用 finally ?

上下文:在 SPA 应用程序(Aurelia/ASP.NET Core Web API)中,我试图向用户表明当前正在从 Web API 获取数据。获取完成后,即使抛出异常,我也想删除 UI 指示。我正在考虑将它包装到一个“RAII 类”中以便重用和更简洁的语法(所以我不必用 finally 来填充代码)......

最佳答案

没有using Typescript 中的语句,你总是可以依靠 try-finally这是什么using无论如何是 C# 中的语法糖。

另一种方法是创建自己的 using带功能。

interface IDisposable {
dispose();
}

function using<T extends IDisposable,
T2 extends IDisposable,
T3 extends IDisposable>(disposable: [T, T2, T3], action: (r: T, r2: T2, r3: T3) => void);
function using<T extends IDisposable, T2 extends IDisposable>(disposable: [T, T2], action: (r: T, r2: T2) => void);
function using<T extends IDisposable>(disposable: T, action: (r: T) => void);
function using(disposable: IDisposable[], action: (...r: IDisposable[]) => void)
function using(disposable: IDisposable | IDisposable[], action: (...r: IDisposable[]) => void) {
let disposableArray = disposable instanceof Array ? disposable : [disposable];
try {
action(...disposableArray);
} finally {
disposableArray.forEach(d => d.dispose());
}
}


// Usage
class UserNotify { dispose() { console.log("Done"); } }

class Other { dispose() { console.log("Done Other"); } }

using(new UserNotify(), userNotify => {
console.log("DoStuff");
})
// It will type the arrow function parameter correctly for up to 3 parameters, but you can add more overloads above.
using([new UserNotify(), new Other()], (userNotify, other) => {
console.log("DoStuff");
})

如果你想将它与 promise 一起使用,你可以创建一个异步版本,其中一次性返回一个 promise 和 action参数也返回一个 promise :
interface IDisposableAsync {
dispose(): Promise<void> | void;
}
function usingAsync<T extends IDisposableAsync, T2 extends IDisposableAsync, T3 extends IDisposableAsync>(disposable: [T, T2, T3], action: (r: T, r2: T2, r3: T3) => Promise<void>): Promise<void>;
function usingAsync<T extends IDisposableAsync, T2 extends IDisposableAsync>(disposable: [T, T2], action: (r: T, r2: T2) => Promise<void>): Promise<void>;
function usingAsync<T extends IDisposableAsync>(disposable: T, action: (r: T) => Promise<void>): Promise<void>;
function usingAsync(disposable: IDisposableAsync[], action: (...r: IDisposableAsync[]) => Promise<void>): Promise<void>
async function usingAsync(disposable: IDisposableAsync | IDisposableAsync[], action: (...r: IDisposableAsync[]) => Promise<void>): Promise<void> {
let disposableArray = disposable instanceof Array ? disposable : [disposable];
try {
await action(...disposableArray);
} finally {
for (let d of disposableArray) {
let result = d.dispose();
if (result !== null) {
await result;
}
}
}
}

// Usage
class UserNotify { dispose() { console.log("Done"); } }
class Other { dispose() { console.log("Done Other"); } }
function delay() {
return new Promise((r)=> setTimeout(() => {
r();
}, 100));
}
(async function () {
await usingAsync(new UserNotify(), async userNotify => {
await delay()
console.log("DoStuff");
})

await usingAsync([new UserNotify(), new Other()], async (userNotify, other) => {
await delay()
console.log("DoStuff");
})
})();

关于typescript - TypeScript 中的 IDisposable/RAII?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47788722/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com