This is where Lisp's unwind-protect, finally blocks in some languages, defer in Go, and C++'s RAII pattern can come in handy. Especially if you have a healthy respect for goto and want to minimize its presence in your code for various reasons.
`defer`, on the other hand, is probably the only thing I wanted to take from Go to other languages I worked with. Beautifully explicit and wonderfully useful.
Old:
using (var file = OpenFile())
{
// use file
}
New: using var file = OpenFile();
// file will be disposed when it goes out of scopeIt would be cool if someone made a way to scope variables at the function level in JavaScript instead of at the block level. I might write a transpiler for it…
https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md
So, impostor syndrome aside, why not? Wanna team up on that?
It would be nice if there were an equivalent in the native API. You can use .finally() with chained promises, but as far as I know there's nothing comparable with async/await yet, and that's a much more comfortable syntax with which to work with promises overall.
That said, I much prefer early return whenever it makes sense. In functions that do have a lot to unwind and many possible points of failure I'll pull out the old villain 'goto' and have the unwind code at the bottom of the function.
Strictly sticking to only one approach is usually a mistake. One that is repeated a lot in computer science. There are schools of thought that if everything is the same it will be easier to understand, but what happens is problems that don't exactly fit the mold end up being solved in awkward and inefficient ways. Or development gets slowed because you have to refactor your problem around the tools instead of the other way around.