Why does it increase each time? - timer

I want to understand why the number of timer keeps increasing whenever it is in use.
Should it start from a fresh number each time?
And why does it increase 2 or 4 each but not 1?
$(document).ready(function(){
endAndStartTimer();
});
var timer;
function endAndStartTimer() {
window.clearTimeout(timer);
//var millisecBeforeRedirect = 10000;
timer = window.setTimeout(function(){alert('Hello!');},1000);
alert(timer);
}
Do I need window.clearTimeout(timer); inside the function? What would it be wrong if I d
you can try it here.
Thanks.

Some simple facts
You don't have to call clearTimeout before setting one. At least not in the code you provided.
When I run your JSFiddle in FF4 it always reports 2
Timer IDs are generated by Javascript engine implemented in the browser so you don't have much control over it. Whatever it returns is value that you have to use to clear it. I haven't tested it but it may as well be that these ID generators are implement in a different way. Although the simplest (=fastest) way is by simply incrementing the ID of the last timer ID.

The method returns unique timer ID. The only purpose is to give you a handle to use it with clearTimeout. You can't control what id is generated.

Related

Angular avoid function expression from running multiply times

I have multiply functions like count() getTotal(). All those calculation functions have to run if something changes my cart/object.
Currently I'm using them in the view like {{count()}}. So all those functions are running multiply times.
I think those functions are called multiply times, because of the dirty checking. Is this correct?
Now I read about the $watch function and that you should try to avoid it, because of performance issues. Anyway I wanted to test it, and $watchedmy cart. I found out it only logs a single time so wouldn't it be faster to $watch my cart and call all the calculations functions in there and then just bind to the result of the calculations?
I'm a bit confused know, cause i thought it would have the same behaviour. Because the $watch will also go through the digest loop.
I know there are already a lot of similiar questions, but having somebody explaining it directly for my case in a not so hard english, would make it a lot easier.
Example:
What has better performance? and why? Does both variants go through the digest cycle? Why then Variant 2 logs 10 times and Variant 1 only 1 time?
Variant 1
// bind these to scope and show like {{totalGross}}
cartService.totalGross = null;
cartService.totalNet = null;
cartService.totalItems = null;
// watch the cart here and update all variables
$rootScope.$watch(function () {
return cartService.cart;
}, function(){
cartService.totalGross = cartService.getCartTotalGross();
cartService.totalNet = cartService.getCartTotalNet();
cartService.totalItems = cartService.getTotalItems();
}, true);
Variant 2
// bind these to scope and show like {{getCartTotalGross()}}
cartService.getCartTotalGross();
cartService.getCartTotalNet();
cartService.getTotalItems();
Trying to answer my own question, altough i'm not shure if it's correct.
Variant 1 you have 1 more watcher, but we just watch values instead of functions and the 1 more because we watch the cart manually with $watch. But the watchers are less heavy to compute.
Variant 2 we are watching the value that functions are returning, so the functions have to calculate the same value multiply times, witch is more heavy. In each digest Cycle the UI get updated
Is this correct? So Variant 1 is better for performance?
It's generally considered bad practice to use $watch not (only) because it has performance issues, but because there are, most of the time, better alternatives (both clearer, and more efficient).
For example, instead of watching a model value that changes when the user enters something in an input, in order to compute something that depends on this value, you can use ng-change on the input and call the computation from there. This is faster, and the intent is clearer.
Now, to answer your question:
Every time an event is handled by angular, the event handler can modify anything in the scope. Angular has no way to know what has been modified. So it has to call, for example, getTotalItems() because an event handler might have changed something that makes the returned value of getTotalItems() change.
Additionally, changing any value that is watched causes a watcher function to be executed, and this watcher function can, in turn, change other values, that can be watched by other watchers, etc. etc. So angular needs to evaluate all the watched expressions in a loop, until it can be sure that the last evaluation leads to the same results as the previous one. That's what is known as the digest loop.
So, in short, having {{ getTotalItems() }} in the view is not a big deal if that function just returns something simple, like the length of an array, or the sum of a few values. But if it computes the meaning of life, it's a really bad idea, and you should instead compute the meaning of life only when it needs to be computed, and store the result in a variable that is displayed in the view.
You can do that with a watcher, but that should be the last resort. As I said already, there are often better alternatives.

How to wait until an element is not changing in Selenium Webdriver?

I have begun to use explicit wait more and more to deal with asynchronous event on the page. For example i will wait for an element to be clickable before clicking it.
However many time i also face the situation when i need to wait an element to become stable, i.e. stop changing, before i will act on it. For example, i may do a query on a page, and wait for the search result (either shown in a list or a table) to stop changing, and then retrieve the results.
Off course, there will be a timeout period for this wait. So in a nutshell, i want to wait for a list or table while its values are not changed, say for 5 sec.
How to implement this kind of wait? Could anyone give a simple example in code, if possible?
Thanks,
Using FluentWait will do the job. Its advantage to implicitWait and explicitWait is that it uses polling and timeout frequency. For example, we have a timeout value of 5 seconds and 1 second for polling frequency. The element will be checked for every 1 second until it reaches the timeout value (5 sec). An exception is thrown if the timeout value is exceeded without having any result.
FluentWait is helpful in AJAX applications as well as in scenarios when element load time fluctuates often because it ignores specific types of exceptions like NoSuchElementExceptions while waiting for an element.
You can check the sample code for FluentWait here
I would do something like this. Basically you want to count what is changing, e.g. table rows, list elements, etc., wait X seconds, count again. If the count didn't change, you are done. If it did change, wait again.
int count = 0;
int newCount = 0;
boolean done = false;
while (!done)
{
newCount = driver.findElements(...).size();
if (newCount > count)
{
count = newCount;
}
else
{
// no new results, stop waiting
done = true;
}
Thread.sleep(2000);
}
Depending on your scenario, you might want to add an overall timeout so that you never exceed X minutes or whatever. Just add that to the while condition.

Most efficient way to increment a value of everything in Firebase

Say I have entries that look like this:
And I want to increment the priority field by 1 for every Item in the list of Estimates.
I can grab the estimates like this:
var estimates = firebase.child('Estimates');
After that how would I auto increment every Estimates priority by 1?
FOR FIRESTORE API ONLY, NOT FIREBASE
Thanks to the latest Firestore patch (March 13, 2019), you don't need to follow the other answers above.
Firestore's FieldValue class now hosts a increment method that atomically updates a numeric document field in the firestore database. You can use this FieldValue sentinel with either set (with mergeOptions true) or update methods of the DocumentReference object.
The usage is as follows (from the official docs, this is all there is):
DocumentReference washingtonRef = db.collection("cities").document("DC");
// Atomically increment the population of the city by 50.
washingtonRef.update("population", FieldValue.increment(50));
If you're wondering, it's available from version 18.2.0 of firestore. For your convenience, the Gradle dependency configuration is implementation 'com.google.firebase:firebase-firestore:18.2.0'
Note: Increment operations are useful for implementing counters, but
keep in mind that you can update a single document only once per
second. If you need to update your counter above this rate, see the
Distributed counters page.
EDIT 1: FieldValue.increment() is purely "server" side (happens in firestore), so you don't need to expose the current value to the client(s).
EDIT 2: While using the admin APIs, you can use admin.firestore.FieldValue.increment(1) for the same functionality. Thanks to #Jabir Ishaq for voluntarily letting me know about the undocumented feature. :)
EDIT 3:If the target field which you want to increment/decrement is not a number or does not exist, the increment method sets the value to the current value! This is helpful when you are creating a document for the first time.
This is one way to loop over all items and increase their priority:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
estimatesSnapshot.forEach(function(estimateSnapshot) {
estimateSnapshot.ref().update({
estimateSnapshot.val().priority + 1
});
});
});
It loops over all children of Estimates and increases the priority of each.
You can also combine the calls into a single update() call:
var estimatesRef = firebase.child('Estimates');
estimatesRef.once('value', function(estimatesSnapshot) {
var updates = {};
estimatesSnapshot.forEach(function(estimateSnapshot) {
updates[estimateSnapshot.key+'/priority'] = estimateSnapshot.val().priority + 1;
});
estimatesRef.update(updates);
});
The performance will be similar to the first solution (Firebase is very efficient when it comes to handling multiple requests). But in the second case it will be sent a single command to the server, so it will either fail or succeed completely.

Having to use DelayedTask otherwise LoadMask doesn't show

I am doing a few processes that take time so I want to be able to show a mask, I use LoadMask. Problem is that the code that I want to run seems to run too quick and I presume is blocking the UI to show the mask. The process takes around 4 seconds so I know the mask isn't being enabled and disabled at the same time.
The way I got around this was to use a delayed task, but it kind of feels like a code smell.
Can I do this a different way?
Here is what I have
var myMask = new Ext.LoadMask(win, {});
myMask.show();
var task = new Ext.util.DelayedTask(function () {
....... // DO MY stuff and eventually do a myMask.hide()
task.delay(400);
It works great but I was wondering if this is the right way to go ?
If I remove the delayedtaks then the mask never seems to display, but the process does work.
Assuming your "process" is some kind of local sequential procedure, what you said above is pretty much correct. If your code is running a busy loop it won't relinquish control to the UI "thread" for the browser to redraw.
So you won't see the mask here;
mask();
busyLoop();
unmask();
But if you do:
mask();
setTimeout(function() {
busyLoop();
unmask();
}, 1);
It gives the browser time to draw before you get into your stuff.

AngularJS - ng-grid sliding window - table not updating from array change

I'm trying to use ng-grid with a sliding window of 100 records. The data is coming in realtime via signalR and every message trigger the following method:
onNewTrades(records) {
console.log("onNewRecord", records);
if (connectionStopped) return;
for (var i = 0; i < records.length; i++) {
if ($scope.recordsData.length > maxRecordsInTable)
$scope.recordsData.pop();
$scope.recordsData.unshift({
t: new Date(records[i][0]),
p: records[i][1],
a: records[i][2]
});
}
}
I have a threshold of 100 maxRecordsInTable before I start popping items off the end (before adding the new message to the front)
However, when it reaches my threshold the table simple stops updating. Strangely though, if I set a breakpoint on unshift(), the table does update with every "continue".
I suspect it's some kind of angular timing issue? I tried using $timeout()
Or may when I pop() and unshift() at the same time it doesn't pick up a change in the array? I tried using $apply() (error already in digest cycle)
There are a few things that could be happening here.
First of all, if onNewTrade is using an external, non-angular, library making xhr requests outside of angular's framework (i.e. not using $http or $resource), you have to call $scope.$apply(function(){ }) around the code you want the scope's digest to know about. That part's not clear from what you've provided. edit: Read more about when to use $scope.$apply
Second, angular's digest phase does a minimum of two passes (first to make changes, second to make sure there are no more changes). It does at most 10 passes by default. If angular evaluates the scope 10 times and it is not consistent, it gives up. see documentation. It does this because you can have multiple watch functions where one watch affects the scope higher in the hierarchy, which makes changes and affects the same watch.. basically causing an evented infinite loop. Do you see a console error about '10 $digest iterations, aborting!' or something similar?
There are a couple of other questionable things:
is onNewRecord asynchronous? If so, I would doubt connectionStopped is being done correctly. You could be returning early. Because you say a breakpoint shows values on unshift, its probably not the cause of this issue (and most likely missing $scope.$apply is the problem), but I'd rethink this code.
Your function is onNewTrade(records), but you log onNewRecord(record). If you have nested variables here, make sure you haven't excluded code that may contain typos (e.g. record instead of records). You might be working on an unexpected object.

Resources