...再利用とクリーンな構文については、「RAIIクラス」(私は唐辛子にfinally
を使用してコードを持っていない)にそのをラップに探していますいずれにしてもtry-finally
に戻ってください。using
はC#の構文的な砂糖です。
もう1つの方法は、独自の機能を持つusing
を作成することです。
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");
})
})();
:あなたは約束でそれを使用したい場合は
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");
})
、あなたは使い捨てのリターンが約束とaction
パラメータは、同様の約束を返すに非同期バージョンを作成することができます