-
Notifications
You must be signed in to change notification settings - Fork 3
Allow AsyncDisposableStack to also add synchronous items #14
Description
So it's possible to have resources that define both [Symbol.dispose] and [Symbol.disposeAsync]:
const fileResource = {
[Symbol.dispose]: () => { fs.closeSync(fd); },
[Symbol.disposeAsync]: async () => {
return await new Promise((resolve) => {
fs.close(fd, () => resolve());
});
}
}Within a block we could use either using or await using to pick which disposal method to use:
{
using fileResourceSync = makeFileResource();
await using fileResourceAsync = makeFileResource();
}However under the semantics of asyncDisposableStack.use, it will always use [Symbol.disposeAsync] regardless of which we might wish to use.
Furthermore (although less important IMO) is the fact that even if [Symbol.disposeAsync] is not on the resource, a microtask will occur between successive sync cleanups, which could be observed:
asyncDisposableStack.use({
[Symbol.dispose]: () => {
console.log("Cleanup res1");
Promise.resolve().then(() => console.log("Before cleanup res2"));
},
});
asyncDisposableStack.use({
[Symbol.dispose]: () => {
console.log("Cleanup res2");
},
});I'd like to propose that we have an additional .useSync method on AsyncDisposableStack so that we choose to use [Symbol.dispose] even if [Symbol.disposeAsync] for the resource were available.
(NOTE: I am not proposing that asyncDisposableStack.dispose() changes in any-way, this would still unconditionally return a promise).
This would be a fairly minimal addition, the spec text is pretty much the same as .use just with the other hint:
AsyncDisposableStack.prototype.use( value )
When the use function is called with one argument, the following steps are taken:
1. Let asyncDisposableStack be the this value.
2. Perform ? [RequireInternalSlot](https://tc39.es/ecma262/#sec-requireinternalslot)(asyncDisposableStack, [[AsyncDisposableState]]).
3. If asyncDisposableStack.[[AsyncDisposableState]] is disposed, throw a ReferenceError exception.
4. Perform ? [AddDisposableResource](https://tc39.es/proposal-async-explicit-resource-management/#sec-adddisposableresource-disposable-v-hint-disposemethod)(asyncDisposableStack.[[DisposeCapability]], value, sync-dispose).
5. Return value.