4 ms·
Scoped resources are essential for avoiding global singletons. The JS/Node ecosystem acts like (and often believes) globally-scoped singletons are a recommended
by computomatic 3y ago
Scoped resources are essential for avoiding global singletons. The JS/Node ecosystem acts like (and often believes) globally-scoped singletons are a recommended pattern for things like database connections.
The reality is, there’s no better option at the moment.
Virtually every other ecosystem has concluded globals are not the best practice. (At least until we return to dependency injection containers where they are suddenly cool again but I digress.)
- skybrian 3y agoIt can be useful take a step back and think about where best practices come from. What problems do they solve? Singletons are bad in complicated, long-running processes, because you're in trouble if you want to have more than one of something, and cleanup can be a problem. A one-to-one relationship with the running process is problematic. But JavaScript often runs in a disposable runtime environment that forces cleanup when terminated. For example, a web page or a web worker. Memory leaks usually aren't a problem and you can just treat it like arena allocation. If you want more than one web page, it's very easy to do. Similarly, if you're writing scripts using disposable Unix processes then a memory leak in a command isn't all that big a deal; you can sometimes get away with never freeing anything because the OS will do it.
- AlphaSite 3y agoI think from a threading perspective that’s a reasonable statement. But it’s also about creating manageable abstractions, very limited singleton usage ok, but it can easily get out of hand and lead to hard to reason about code.
- randomdata 3y agoSingletons are considered 'bad' under general advice because they can make testing hard. As with everything, there is a time and a place, but if you understand the tradeoffs to recognize that time and place you won't be soliciting random advice from the internet, and thus won't hear the 'good'. I get the impression that the JavaScript world largely doesn't care much for testing, though.
- lghh 3y agoWhen using singletons for DB connections in TS, I will generally have a singleton function that returns the resource. So getDatabaseConnection will return a databaseConnection. It’s pretty simple, but it has solved the testing problem for me because within that getResource function I can check if the environment being ran in is a test environment. If so, return a mocked instance. If not, return the real instance. It’s pretty rudimentary, but it’s solved our issues.
- tracker1 3y agoNote, you can also place said singleton as a single export in a module, and test anything using that module with a mock on the loader, which most of the newer testing options for JS support pretty easily.
- sroussey 3y agoNodeJS, however, is not running in a disposable runtime environment. It is also the location where things that need cleanup are likely to occur (database connections, for example). For the browser context, I don’t have a good use case for ‘using’ (except for browser devs themselves where some code could be in JS now but impossible before). Then again, people always surprise you with new use cases!
- randomdata 3y agoI rarely write Javascript, so I'm not in tune with the community, but when I have I have had no trouble passing database handles and such things around like I'm used to in every other language I work with more frequently. It appears all this does is avoids needing to manually call close (or equivalent)? While that is a nice addition, helping to avoid the situation where you forget, why does globals become the alternative? Isn't simply calling close manually the best option at the moment?