Post AhtVNLSxqhA5eDCcBE by develwithoutacause@techhub.social
(DIR) More posts by develwithoutacause@techhub.social
(DIR) Post #AhtVNLSxqhA5eDCcBE by develwithoutacause@techhub.social
2024-05-06T06:13:52Z
0 likes, 0 repeats
#JavaScript How does the new resource management proposal clean up async disposables?IIUC, it seems like it will inject an `await` into the scope close, when the object is disposed. That sounds very intuitive to me. Consider this snippet:```let x = 1;if (x) { // ... console.log('first', x);}console.log('second', x);```The two console log should always print the same thing right? No statements can happen between them (assuming a dispose operation does not change `x`).Except that's not true with `await using`:```let x = 1;if (x) { await using stack = /* ... */; setTimeout(() => x++, 50); console.log('first', x);}console.log('second', x);```There's a very sneaky race condition here. `await using` implies that line awaits, but it really means that the `}` line awaits.That seems very unintuitive to me and requires the reader to check every line in the block to know the behavior of `}`. That feels brittle to me.Am I missing something here?
(DIR) Post #AhtVNMhBHK7zSarTyi by develwithoutacause@techhub.social
2024-05-06T06:15:58Z
0 likes, 0 repeats
I guess in theory you can have a similar problem with synchronous dispose functions, but that requires the disposal to directly trigger the change in state and doesn't affect execution timing.Async disposables feel much more fragile as a result. In particular the syntax-less await on the `}` line feels *very* sketchy to me.
(DIR) Post #AhtVNOaWF3zHKVlBs8 by develwithoutacause@techhub.social
2024-05-06T19:31:18Z
0 likes, 0 repeats
I tried this out and found that my understanding does appear to be correct, there is indeed a very sneaky `await` at the `}`.https://www.typescriptlang.org/play/?target=9&module=1#code/CYUwxgNghgTiAEBzCB7ARlC8DeAoe8AlgHYAuIMAZlGAgMoCeAtmihAMIrEDOpMArmFIoYOfAXhwowLhAbxghbgAcU3EAC54-YoQCO-BN2asIAbnEEpM4nPhRjxMABElq9Vp37D8YyzYWBAC+uOIk5FQ0CK4qalBoEAh4EvAA2oz+EAB0irHqALoAFACUWgBuKITAgfAhYWQU1LTwAIKOLm5xCUmWaRmmWQ4MTjHuIEWl8AAKMChMSiAAPBVVAHw1IXWF-Wz23PbEDMU5nerwALzwOxCFAOS5Y7fFFtsmuw4HR4Pto2oIl9c7kMRqcQE8LLhIA59gBZBi-bjxRJEJjKRJMEBkfZtYYdPJInoEZQwQhlKDkSQgaSyeRgTAQDBgADW3C0LRgMCgDEWJQuq3gK2A8AAPtNZvN1MtKsBVvzLql8hCifwEoQwAoQJQKIU6RAGTQmVpeed+YLJoKxClSAALJRZXX65ncLLKfjca06+mMpnPcR1IkkskUh5-IWXagQdQ1V2q9XA9XpN7ZeMI8YlLQzOYLKVrS0SQiUeCFG12kPqYDFeA22YAd3gxBAdYAohyRHcWhBrPIyyAhSIFKcSIhwb0S86e2GqwIQEqJFAa1BCKQxVn1IM9cXbc6Hd7nUwoMpCjq0JWTfAwGgSsVfcFcFt40XT-zkvBEsuAB4XeAARhqBaL76Vi+BDzouy5ukOlL7JcDZ1nCCIEiUNRWCA46atqxr8qQhAYig-CkIUADsACs16zgQ2G4fhhTEQADMcNqYkeT7wO+ADUbG+r0YBcNwbAgFkqCIHclCEDAvC3AANKxN61PAAD08nwAAElUoDEPAAAGoFLpp8DWhQAniDxPD8YJKDCbc6gmcAUkyRYQTFEhoSUDoQiEFwVY4SAeEEaA0AMFoxD8CwFCTJmEpLIKz7iHApD8DAGmwSukU5jKR5wHxEBlCALHAb4ICkAAKt5vnMXyOBQWwOVIbU0n+VysmOQ5oQgO+qgwMu2BBBYQA
(DIR) Post #AhtVNQVz4tY3J1eb56 by develwithoutacause@techhub.social
2024-05-06T19:47:40Z
0 likes, 0 repeats
Personally, I'd much rather see a block syntax like:```using (const res = getResource()) { // ...} // Executes `res[Symbol.dispose]()`.```Async can work just like `for await`:```using await (const res = getResource()) { // ...} // Executes `await res[Symbol.asyncDipose()]()````That feels much clearer to me as `using` will _always_ carry the requirement that dispose happens at the `}` and even `awaits` for the async case.I'm sure the spec authors considered this as many examples in this issue reference a block-style syntax.https://github.com/tc39/proposal-explicit-resource-management/issues/15I don't see a single consolidated summary for exactly _why_ they didn't go with that approach however.