-
Notifications
You must be signed in to change notification settings - Fork 0
Description
This proposal's name is "strict enforcement of using", but while it solves the footgun of forgetting using, it is not strict against unintended usage of the disposable API.
You might expect that a strict enforcement of an RAII-like pattern would guarantee not only that the [Symbol.dispose] method is always called, but that it is called before the current function returns, and that the ordering of [Symbol.enter] and [Symbol.dispose] calls across multiple disposables is properly stacked. Since this proposal allows JS code to call the [Symbol.enter]() and [Symbol.dispose]() methods, it guarantees none of these properties.
As an example use case where these properties matter, in the AsyncContext proposal we were discussing the possibility of a disposable API (see tc39/proposal-async-context#60 and nodejs/node#52065), that would switch the current context when entered and restore the previous one when disposed. However, since the AsyncContext machinery is unaware of function boundaries, the possibility of an entered but non-disposed scope would pollute the caller's context:
import { callee } from "some-library";
const asyncVar = new AsyncContext.Variable();
function caller() {
asyncVar.run(42, () => {
console.log(asyncVar.get()); // 42
callee();
// As the AsyncContext proposal currently stands, there would be nothing
// callee can do that can make asyncVar.get() not return 42. However...
console.log(asyncVar.get()); // undefined
});
}// some-library
// The AsyncContext snapshot at the time this module was evaluated, which is
// likely empty.
const initialSnapshot = new AsyncContext.Snapshot();
export function callee() {
const scope = new AsyncContextScope(initialSnapshot);
scope[Symbol.enter]();
}Now, it is possible that this is a one-off, or a special case, and that most disposables would benefit from fixing the footgun without needing this level of strictness. But that would need to be looked into.