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.
Related
I watch a lot of programming tutorials and challenges using HTML5 canvas and Javascript (mainly by Dan Shiffman or The Coding Train) and I try to follow along while changing the code in order to make it my own.
I've noticed a lot of the programmers creating variables (e.g. let num;) and then assigning the values inside of an init() function.
What is the difference between doing that and just assigning the value to the variable in the same line (e.g. let num = 1;)?
I've tried doing both and I don't see a difference so I'm thinking it's maybe a slight performance boost?
Assigning the values inside a function will allow you to call that function from anywhere, rather than being stuck at assigning only at the initialization location. From a practical perspective, assuming you understand scope and the temporal dead zone, this can be helpful for:
Code organization. If you put the meat of your code into functions and then call the functions all together later, it can be easier to visualize the higher-order process of what's going on, and in what order the various chunks of code need to run in. If the code is long, it can be easier to understand what init() means than to understand what <200 lines of setup code> means.
Less repetitiveness. Say that at some point when the application is used, either you or the user want to reset the state of the app back to how it was originally. (For example, a "Play Again" button on a game.) Then, rather than having to write <200 lines of setup code> again, you'd just have to write init() again.
maybe a slight performance boost?
This has no effect on performance.
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.
In my app I am receiving data via an HTTP channel that's handled in a custom way. I'm building some [data] objects from the pipe, wrap them in a scope.$new(true) and when I receive an update call childScope.$apply() to set the new properties.
This works fine for light loads, all the watchers get notified and has really been running without any issues or missed updates.
Now I'm trying to push a lot more updates and don't know if the pattern used above is the way to go. I think (though have not checked) that each call to $apply calls the digest on the root scope and I want to coalesce these on browser cycles or ~50ms intervals. Currently, whenever I receive ~100 updates on 5000 objects/scopes it kills the browser.
I saw that angular docs say each scope has an $applyAsync method but I cannot find it anywhere, this would be essentially what I am after.
Is this a bad idea and the performance is already good enough? Should I implement my own applyAsync method by using $browser.defer() or some other method?
Edit: just tested the code and indeed the $rootScope.$digest is called for each child scope $apply(). Perhaps moving this part away from Angular JS and using a listener-based approach is better, so this is also a valid answer.
In the end I used evalAsync and this seems to work as intended.
I probably need to call $digest (or $apply) every so often to make sure there are no pending scope changes but I have not seen the need to do this yet.
So my idea would be to:
call evalAsync for all the scope changes that need to happen very fast
increment a counter before the evalAsync call
set a variable with the current time inside the evalAsync function parameter and decrement the counter
on a timer (50-100ms) see if the counter is >0 and if the last evaluation time was some time ago (>50-100ms) and if yes force a digest loop.
I will not mark this as a correct answer since it does not seem like the best idea but it was the best I could come up with and it does the job as intended.
So, I'm trying to improve my javascript skills and get into using objects more (and correctly), so please bear with me, here.
So, take this example: http://jsfiddle.net/rootyb/mhYbw/
Here, I have a separate method for each of the following:
Loading the ajax data
Using the loaded ajax data
Obviously, I have to wait until the load is completed before I use the data, so I'm accessing it as a callback.
As I have it now, it works. I don't like adding the initData callback directly into the loadData method, though. What if I want to load data and do something to it before I use it? What if I have more methods to run when processing the data? Chaining this way would get unreadable pretty quickly, IMO.
What's a better, more modular way of doing this?
I'd prefer something that doesn't rely on jQuery (if there even is a magical jQuery way), for the sake of learning.
(Also, I'm sure I'm doing some other things horribly in this example. Please feel free to point out other mistakes I'm making, too. I'm going through Douglas Crockford's Javascript - The Good Parts, and even for a rank amateur, it's made a lot of sense, but I still haven't wrapped my head around it all)
Thanks!
I don't see a lot that should be different. I made an updated version of the fiddle here.
A few points I have changed though:
Use the var keyword for local variables e.g., self.
Don't add a temporary state as an object's state e.g., ajaxData, since you are likely to use it only once.
Encapsulate as much as possible: Instead of calling loadData with the object ajaxURL, let the object decide from which URL it should load its data.
One last remark: Don't try to meet requirements you don't have yet, even if they might come up in the future (I'm referring to your "What if...?" questions). If you try, you will most likely find out that you either don't need that functionality, or the requirements are slightly different from what you expected them to be in the past. If you have a new requirement, you can always refactor your model to meet them. So, design for change, but not for potential change.
I've been reading about custom events in jQuery and why they should be used but I'm still clearly missing the point. There is a very good article I read here that has the following code example;
function UpdateOutput() {
var name = $('#txtName').val();
var address = $('#txtAddress').val();
var city = $('#txtCity').val();
$('#output').html(name + ' ' + address + ' ' + city);
}
$(document).bind('NAME_CHANGE ADDRESS_CHANGE CITY_CHANGE', function() {
UpdateOutput();
});
$('#txtAddress').keyup(function() {
$(document).trigger('ADDRESS_CHANGE');
});
$('#txtCity').keyup(function() {
$(document).trigger('CITY_CHANGE');
});
Can someone tell me why I just don't call the UpdateOutput() function directly? It would still work exactly the same way, i.e.
$('#txtAddress').keyup(function() {
UpdateOutput()
});
$('#txtCity').keyup(function() {
UpdateOutput()
});
Many thanks
As your article starts with:
As everyone knows, the more dependencies you have in a system, the harder maintaining that system is. Javascript is no exception- and orchestrating actions across complex user interfaces can be a nightmare if not done properly.
Using events removes (some of) these dependencies:
When something happens (a key is released/up), a notification of this event is send, without knowing whether anyone is interested at the moment or not.
When someone is interested in a certain event he can subscribe for it, without knowing why this event was triggered (key released)
Both bullets are independent, the first notifies and the second responds. Removing one does not matter for the functionality of the other. It is also easy to have multiple instances firing/subscribing to events (Also due to the missing dependencies).
Because you are one client of that event, even though you have full control over the entire application. It helps decoupling your code better.
As one of the clients who is interested in knowing when the name, address, or city changes, you are updating the values in some part of the screen. Some other client might want to do something else such as pull up all adjacent cities, reverse geocode the address, do a name lookup on namesdatabase.com, and so on.
You can still control everything without events and call multiple functions directly or put everything in it's own function, but adding events decouples the implementation from what needs to be done, based only on the type of event, so UpdateOutput does not have to worry about pulling up names from a names database, and you don't have to worry about calling all the necessary functions yourself whenever a particular event happens as long as there is a basic understanding of the events defined in the system and what they represent.
A second reason is abstraction. For example, deleting of a user account might get triggered by a simple click, but just by translating that to a higher level event such as DeleteAccount, things would get simpler and understandable when you consider that there could be tens, or hundreds, or maybe even thousands of such events all across the application. Working at a higher level of abstraction than "keyups", "keydowns", "mouseovers", etc. (which are really meaningless anyways in the context of an application and the intent behind), things can get a lot more manageable as the application size grows.
It’s perfectly reasonable to wire up the UpdateOutput() call directly. Often, it’s difficult to represent the need for an abstraction that custom event pooling provides in simple examples.
However, there’s (arguably) two issues of maintainability (again, depending on the use) when calling UpdateOutput directly. The first problem occurs by repeating the UpdateOutput() call in numerous places. This makes refactoring functions (especially those with parameters) extremely difficult when they change. With Event Pooling, you can prep data before passing it to a function, which is helpful when disparate code blocks call the same function. With ajax heavy web apps around, controlling function calls is very important.
Secondly, it’s possible you’ll need to call multiple functions for the same event. Imagine in addition to UpdateOutput(), there’s also some validation function which needs to be fired. Or when a user updates the zip code, some maps api is trigged to show something, or whatever other functionality which could happen (the point being you may have numerous functions being called in a simple keyup() event. Having this wired up directly makes for very large blocks of code which simply call multiple functions, and if there’s conditional logic required, they can get out of hand. Rewritten with event pooling, you get a lot more control of how a function like UpdateOuput is being called, so you don’t need to chase down the method across numerous files. You can simply see what events that cal is binded too.