Using a global variable to prevent code executing repeatedly unnecessarily - javascript

TL;DR: Is it bad practice to use a global variable to prevent code executing unnecessarily, and if so what are the alternatives?
I have an Electron application that reads a stream of real time data from another application and outputs some elements of it on screen.
There are two types of data received, real time (telemetry) data of what is currently going on and more static data that updated every few seconds (sessionInfo).
The first time a sessionInfo packet is received I need to position and size some of the UI elements according to some of the data in it. This data will definitely not change during the course of the application being used, so I do not want the calculations based on it to be executed more than once*.
I need to listen for all sessionInfo packets, there are other things I do with them when received, it is just this specific part of the data that only needs to be considered once.
Given the above, is this a scenario where it would be appropriate to use a global variable to store this information (or even just a flag to say that this info had been processed) and use this to prevent the code executing multiple times? All my reading suggests that Global Variables are never a good idea, but short of allowing this code to execute repeatedly I am unsure what alternatives I have here.
*I recognise that allowing this would probably make no practical difference to my application, but this is a learning experience for me as well as producing something useful so I would like to understand the 'right' approach rather than just bodge something inefficient together and make it work.

Global variables are generally a bad practice for many reasons like:
They pollute the global scope, so if you create a global i, you
can't use that name anywhere else.
They make it impossible or very difficult to unit test your code.
You usually end up needing more of them than you think, to the point where many things become global.
A better practice is to create singleton services. For example, you might create a SessionService class that handles all your auth stuff. Or, perhaps a DataStreamService that holds the state variables of your data stream. To access that singleton, you'd import it into whatever file needs it. Some frameworks go even farther and have a single global data store, like react/redux.

Related

Most efficient way to detect a variable changed and execute a callback

I would like to detect when a variable's value is updated on a server and run a callback that sends the new value to a client in order to provide a real-time feed. For example, say a server generates a random number at random intervals, but it's important for the client to be aware of a new number being generated as soon as it happens.
One simple solution is to define a custom function that you use to set your value instead of directly setting it with '=':
function setValue(val) { a = val; websocket.send(a) }
But that requires going back through already written code and replacing all instances of that variable being updated to instead use the custom function. A tedious and error-prone process but only has to be done once.
Another solution that I read about is to define a setter on the variable when initializing it, as described here.
This would only require replacing all the places where the variable is being initialized for the first time, but since it's listening hidden in the background I worry it reduces readability and someone may forget there's a callback firing each time the variable is being updated.
I don't code professionally so I'm not sure which of these solutions would be more widely accepted, or if there's a better way I should be approaching it. Also not sure of the performance hit this would cause but I'm guessing pretty negligible.
Define the custom function. Take the refactor pain now and keep it readable. Coding is 20% creation and 80% maintenance, but it always feels like 99% creation and 1% maintenance when you’re in the thick of making something new.

REST API Ajax simultaneously requests

Is it wrong to make multiple ajax simultaneously requests to different endpoints of a REST API that end up modifying the same resource?
Note: each endpoint will modify different properties.
For example, let's assume that one endpoint modifies some properties for an order, like order_date and amount and another endpoint set's the link between the same order and a customer by changing the customer_id value from the orders table (I know that maybe this is not the best example, all these updates can be done with one endpoint).
Thanks in advance!
This is totally a requirements based question. It is generally a bad idea to have a single resource be changed by multiple processes, but this ONLY matters if there is a consistency relationship between the data. Consider some of the following questions:
If one or more of the AJAX calls fails does will that break your application? If it will, then yes, this is a bad idea. Will your application carry on regardless of what data you have at any given time? If so, then no this doesn't matter.
Take some time to figure out what dependencies you have between your data calls and you will get your answer.
what you are describing is not a shared resource even if it is stored in the same object because you are modifying different properties however take great care when using same object. if your requests to the server depends on the properties that are modified by the other request.
in general its not a good idea to use the same object to store data that is modified by more than one asynchronous function even if the properties are different. it makes your code confusing and harder to maintain since you have to manually coordinate your function calls to prevent race condition.
there are better ways to manage your asynchronous code using Promises or Observables
It's a bad idea in general. But if your code is small and you can manage it then you can do it though its not recommended.
In the long run, it will cause you many problems confusion, maintaining code, consistency etc.
And if in any case another developer has to manage your code, It will be more confusing and tough for him.
In programming always keep things flexible and think in long run. Your requirements can change in future , what will you do then? write the whole program again? This is one thing , you also want to avoid.

Is it safe to use and update global variables in NodeJS?

I have a node server for loading certain scripts that can be written by anyone. I understand that when I fire up my Node server, modules load for the first time in the global scope. When one requests a page, it gets loaded by the "start server" callback; and I can use all the already loaded modules per request. But I haven't encountered a script where global variables get changed during request time and affects every single other instance in the process (maybe there is).
My question is, how safe is it, in terms of server crashing, to alter the global data? Also, suppose that that I have written a proper locking mechanism that will "pause" the server for all instances for a very short amount of time until the proper data is loaded.
Node.js is single threaded. So it's impossible for two separate requests to alter a global variable simultaneously. So in theory, it's safe.
However, if you're doing stuff like keep user A's data temporarily in a variable and then when user A later submits another request use that variable be aware that user B may make a request in between potentially altering user A's data.
For such cases keeping global values in arrays or objects is one way of separating user data. Another strategy is to use a closure which is a common practice in callback-intensive or event/promise oriented libraries such as socket.io.
When it comes to multithreading or multiprocessing, message passing style API like node's built-in cluster module has the same guarantees of not clobbering globals since each process have its own global. There are several multithreading modules that's implemented similarly - one node instance per thread. However, shared memory style APIs can't make such guarantees since each thread is now a real OS thread which may preempt each other and clobber each others memory. So if you ever decide to try out one of the multithreading modules, be aware of this issue.
It is possible to implement fake shared memory using message passing though - sort of like how we do it with ajax or socket.io. So I'd personally avoid shared memory style multithreading unless I really, really need to cooperatively work on a very large dataset that would bog down message passing architectures.
Then again, remember, the web is a giant message passing architecture with the messages being HTML and XML and json. So message passing scales to Google size.

Can variables in JS function closures be accessed in any way (including devtools)? How?

In my previous question:
Securing javascript game timing
... it became clear that client-side timing in a Javascript/Canvas game simply won't be secure. I know the mantra about not trusting the client - that is what is causing my struggle in the first place. :-)
So, if I do move all timing to the server and just deal with it, here is a follow-up question. The game obviously needs to be completed before submitting it. As the game puzzle is all Javascript, this introduces the problem of manipulating the client-side code to fake the completion of the game.
I've created the game JS code in a separate class file. If I instantiate the game as such:
var game;
$document.ready(function(){
game = new Game();
});
... then, I can access the 'game' object and all of its methods and variables via the console.
However, if I do:
$document.ready(function(){
var game = new Game();
});
... then I cannot access the 'game' object through the console. This seems to help, but is there something I don't know - can this object still be accessed in some way I don't know about or is making it a private var in that function a little more secure?
Thanks!
Note: there are many other security considerations and attack vectors in such a system. This answer just seeks to answer the specific question that was asked here.
It depends on the browser and what its devtools provide. Most browsers' devtools provide functionality to:
pause execution of JavaScript at any point in time and use a debugger interface.
variables that are in-scope at the current point of execution where the debugger is paused can usually be accessed via devtools in various ways. Inparticular, via console, where anything one can do with that variable in the console is fair game: query its fields, call its methods, etc. If the variable binding isn't const, one can even reassign the variable to a new user-created instance of the object.
navigate JS files and set breakpoints in them.
this is a vector to the above bullet point.
you can make this less attractive by using JS minification (ie. obfuscation), but that's not going to stop someone who's determined.
String literals don't get minified and can usually help a lot in navigating and understanding minified code.
inspect event listeners on HTML elements and set breakpoints on them.
If a variable has a reference bound to it in a function closure that is known to be an event listener of a certain HTML element, or reachable (execution-wise) by such an event listener, this can be another vector to the first bullet point. This can be very common in web games. Just a keyboard event listener usually is an entry-point to reach functions that reference important game objects.
There are even tools to record the JS heap memory. It's a lot of data to sift through, but it's basically everything on the JS heap (readonly).
Given those browser features (and the fact that a user can use any browser they wish), it's impossible to "safeguard" anything 100% on the client-side. It's a losing battle. If you want to play it like a game, you can do your best.
Look into Object.freeze and friends.
freeze or seal anything that can be frozen or sealed, including class prototypes
make variables which can be const const
use assertions to assert in critical parts of the logic that the program state is consistent and try to detect tampering.
Don't care too much about the console. Yes, if there are global objects whose method can easily be fired to "win" the game, it's a nice possibility to cheat, but it can easily prevented as you demonstrated.
So, the hacker would just listen (look at the network pane) which requests are made to your server and fire them manually. If they were just some simple urls like /action=start and /action=end, he could very easily fire them manually without any timing. So you will need to prevent that (although you never can really make it safe), e.g. by adding additional credential tokens. Or you could embed some "secret"(s) into the game code, which are revealed during the gameplay, and need to be sent to the server to prove the rightfulness. Of course they could be read out of your code, but you have to make it too complicated for the hacker. It's a bit like security by obscurity…

Javascript optimization...global variables

I am making a webapp. I have a fairly basic question about javascript performance. Sometimes I need a global variable to store information that is used the entire time the website is open.
An example is a variable called needs_saved. It is true or false to say whether the page needs saved. I might have another variable called is_ie, ie_version, or space_remaining.
These are all variable that I need in various functions throughout the app.
Now, I know global variables are bad because they require the browser to search each level of function scope. But, I don't know if there is any better way to store values that are needed throughout the program.
I know I could create a global object called 'program_status' and give it the properties is_ie, ie_version, etc... But is this any better since it would first have to find my program_status object (stored as a global variable), and then the internal property?
Maybe I'm overthinking this.
Thanks
You have nothing to worry about.
The performance impact of a global variable is minute.
Global variables are discouraged because they can make code harder to maintain.
In your case, they won't.
The reason global variable use should be kept to a minimum is because the global namespace gets polluted when there's a lot of them, and there's a good chance of a clash if your program needs to use some 3rd party libraries which also create their own globals.
Creating a single object to hold all of your global state is a good idea since it limits the number of identifiers you need to reserve at the global level.
To solve performance problems, you can then create a local reference to that object in any scope where you need to access it multiple times:
So instead of
if (globalState.isIe) { alert(globalState.ieMessage); }
you can do
var state = globalState;
if (state.isIe) { alert(state.ieMessage); }
You don't need to do this if you only access the state object once. In any case, even if you never do this, the performance penalties will be negligible.
If you're worried about performance, code something clean then run a profiler on it to optimize. I know both Safari and Google Chrome have one, and it's pretty sure Firebugs includes one for Firefox too. Heck, even Internet Explorer 8 has one.

Categories

Resources