Resource management (eg. try-with-resources)

Isiah Meadows isiahmeadows at
Sat Nov 11 07:18:58 UTC 2017

Here's a C++-inspired alternative:

- `let res = value[Symbol.resource]()` - Get an optional promise to a
resource. lf missing, `res` is set to `value` instead.
- `res[Symbol.close]()` - Close a resource, optionally returning a promise.
- `try let res = value` - Get the resource by invoking
`value[Symbol.resource]()` (or using `value` if the method is missing),
assign it to `res`, and invoke `res[Symbol.resource]()` once it leaves the
scope, even on error.
- `try await let res = value` - Same as above, but await
`value[Symbol.resource]()` (if necessary) and `res[Symbol.close]()` after
calling them.
- `try with expr`, `try await with expr` - Same as above, but without
declaring a binding. (Works well with transactions, locks, etc.)
- Close exceptions replace thrown exceptions.


1. Less nesting, more concise.
2. Java's `try`-with-resources is clunky and awkward. Python's `with`
statement is no different.
3. It works well with sync and async resources.
4. User-level primitives are easier to write.

Of course, in the spec, there's a few logical cases where you'd want these
methods to be defined/used:

- `%IteratorPrototype%[@@close]()` - return `this.close()` if such a method
- `%AsyncIteratorPrototype%[@@close]()` - Similar to above.
- `Atomics.lock(sab, index, size)` - Return a resource that acquires a lock
for this section, and releases on `@@close`.

On Fri, Nov 10, 2017, 10:32 T.J. Crowder <tj.crowder at>

> On Fri, Nov 10, 2017 at 3:00 PM, Michał Wadas <michalwadas at>
> wrote:
> >
> > After I started writing code  extensively using async-await I have
> noticed that I would like to have automated way of dealing with resource
> management.
> This is something I'd really like to see as well.
> What's the motivation for having an `open`? Java's `AutoCloseable` just
> has `close`; one would normally be acquiring these from a constructor or
> function, which is effectively the `open`...?
> Can you give a concrete example using the syntax you're looking at? E.g.,
> were you really thinking of actually having `with` and `as`? If so, I'd
> rather steal more directly from Java (perhaps replacing their `;` with `,`):
> ```js
> try (a = giveMeAResource(), b = giveMeAnotherResource()) {
>     // `a` and `b` are in scope here
> } catch (e) {
>     // ...`a` and `b` are not in scope here
> } finally {
>     // ...`a` and `b` are not in scope here
> }
> ```
> ...where (off-the-cuff):
> * Both `catch` and `finally` are optional
> * `a` and `b` are constants scoped to the `try` block (no need for the
> keyword, but could require or allow it for clarity)
> * Trailing commas on the resource declaration/initializer list are fine
> * `b[Symbol.close]` is called first, then `a[Symbol.close]`
> * Both `close`s are called prior to the execution of code in the `catch`
> or `finally` (if any)
> * If the `try` block throws, that error is the primary error and any
> `close` calls that also throw are "suppressed errors" (more below)
> * If the `try` block doesn't throw, but any `close` calls do, the *first*
> `close` that fails becomes the primary error; any ohers that fail become
> suppressed errors
> Suppressed error handling:
> * If the primary error is an `Error` object, suppressed errors are added
> to a `suppressed` array property on it (creating it if necessary)
> * If the primary error is not an `Error` object, they're lost other than
> being treated as unhandled errors by the environment (for instance: logged,
> perhaps causing script termination; thought required on that)
> -- T.J. Crowder
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list