For Loop with dynamic numbers in timeout - javascript

I have a for loop that is running a timeout function that needs dynamic numbers but instead I'm getting the end result instead of the increments in some cases.
Here's my code (p.s. yes I realize setting 'start' variable inside for loop is not ideal):
var new_answer_start = 0;
var seconds = 0;
for (start=0; start<50; start++) {
new_answer_start = new_answer_start + 50;
seconds = seconds + 10000; //10 seconds
setTimeout(function(){reloadXMLDoc(xmlurl, new_answer_start);},seconds);
}
What I'm trying to accomplish is that increasing every 10 seconds the function will run with the new_answer_start equaling increments of 50. Instead I'm getting every 10 seconds the function is outputting each time starting at 2500 (the last set of numbers after 50 loops). I've had a similar issue before, something to do with closures and I used "let" to fix it then. However when I tried:
let new_answer_start = new_answer_start + 50;
I started getting NaN (not a number) errors. I thought it was weird that the timeout would increment in seconds (10, 20, 30, etc) but not the variable sent to the function. I'm assuming that's because once the function goes to run 10 seconds later, the variable increment has completed to the end. So how do I send the 'fixed' number to the function?
After doing research on similar questions here, I also tried putting the number into a closure:
setTimeout(function(){reloadXMLDoc(xmlurl, (new_answer_start));},seconds);
But this still start outputting at 2500.

Try using an actual closure:
setTimeout((function (new_answer_start) {
return function () {
reloadXMLDoc(xmlurl, new_answer_start);
};
})(new_answer_start), seconds);

window.new_answer_start = 0;
var interval = setInterval(function() {
window.new_answer_start = window.new_answer_start + 50;
}, 10000);

Related

How many times can you make count += 1 in one second with Javascript?

I am trying to measure how many times i can make "count = count + 1" in one second. But this function breaks browser. Anyone can say why is it happening or have a better method to calculate it?
function counter(){
var count = 0;
var trs = true;
while(trs){
count = count + 1;
setTimeout(() => {trs = false;}, 1000);
}
console.log(count);
}
The reason it crashes is because of infinite loop. JavaScript is event driven + single threaded and in JavaScript execution model, the function must finish before it yields control to another function. Thus, the code while (trs) {...} never yields control to the function defined in setTimeout because it never finishes. trs is always true.
Nice visualization on how the JavaScript execution model works: https://blog.avenuecode.com/understanding-the-javascript-concurrency-model
Here's a better way to do it:
function counter() {
var count = 0
var start = Date.now()
var end = start + 1000
while (Date.now() <= end) {
count = count + 1
}
console.log(count)
}
There is an infinite loop over there. Now, since javascript is single-threaded, the browser will get stuck performing that infinite loop, which may cause the cache filling up very quickly and cause a crash (or not re-render anything).
First, generally speaking, it is better to create the setTimeout only once, before you call while:
var count = 0;
var trs = true;
setTimeout(() => {trs = false;}, 1000);
while(trs){
count = count + 1;
}
console.log(count);
However, this will also cause a crash.
You can try to measure the operations differently, measure how much time it takes for a single count = count + 1 operation to run, then find how many of these can be executed in a second (Although it is not the same as running X consecutive operations, which another parameters could influence the result, but I am assuming you care about a single operation or single function you want to measure).
var count = 0;
var t0 = performance.now()
count = count + 1;
var t1 = performance.now()
console.log(1000/(t1 - t0));
If you want it to be inside a loop, you can also include the value check (with if), which the while does before executing its block.
var count = 0;
var trs=true;
var t0 = performance.now()
if(trs==true){
count = count + 1;
}
var t1 = performance.now()
console.log(1000/(t1 - t0));

How to call a function every 1-3 second?

My goal is to write a mini-game using canvas, one of the task is to create "bug" object entering the scene between every 1-3 seconds. I did try functions like setTimeOut,setInterval but I couldn't get it right. Here is my attempt
bugs =[];
function addBug(){
var bug = createBug();
bugs.push(bug);
}
function createRandomNumber(max){
return Math.floor((Math.random() * max) + 1);
};
var enterBug = setInterval(addBug,createRandomNumber(10)*1000);
currently I got it spawning at constant rate but don't know how to change it to every 1-3.Any suggestion? thanks in advance.
Currently, you are only setting the rate once at initial setInterval call. You would likely need to use setTimeout like this:
...
function addBug(){
...
bugTimeout = setTimeout(addBug, createRandomNumber(10)*1000);
}
...
bugTimeout = setTimeout(addBug, createRandomNumber(10)*1000);
You also may think about your random number generation if you want to get more randomness. Right now you can only get exact second values 1-10 since you are multiplying by 1000 to convert to seconds AFTER the random generation is done. If you want something more random you might use:
function createRandomNumber(maxSeconds){
minSeconds = 1;
if (maxSeconds < minSeconds) {
maxSeconds = minSeconds;
}
interval = maxSeconds - minSeconds;
return (Math.floor(Math.random() * interval) + minSeconds) * 1000;
};
You of course would not need to multiply by 1000 anymore when setting timeout.
bugTimeout = setTimeout(addBug, createRandomNumber(10))

delay between function in loop jquery

I have a jQuery function that shows modal boxes:
function ShowAnonce(){
...
jQuery(".ShowAnonce").show();
jQuery(".ShowAnonce").animate({opacity: 1},300).delay(1800).animate({opacity: 0},300);
}
And what I want to do is to show this box 10 times with different random intervals. I used a for loop and setTimeout like this:
for(i=0;i<10;i++){
setTimeout(ShowAnonce(),Math.random()*100);
}
but it shows the box 10 times with no delay. What can I do to fix it?
Also, why can't I do the following at the end of ShowAnonce function?
jQuery(".ShowAnonce").hide();
If I do it, it doesn't shows me box because style display:none keeps being assigned.
Math.random() can return value in decimals also like , 0.123. Which the setTimeout() cannot take . Try Math.ceil (Math.random()) this will give you an integer but might give the same value again and again .
I would try (Math.ceil (Math.random()) *10 ).
As an alternative you can use setInterval as below instead of for loop for x number of times:
var x = 0;
var intervalID = setInterval(function () {
ShowAnnounce();
if (++x === 10) {
window.clearInterval(intervalID);
}
}, Math.random()*100);
Another post about each() iteration gave me an answer. So it works for me:
var time = 0;
for(i=0;i<10;i++){
time = time + Math.random() *10000;
setTimeout(ShowAnonce, time);
}

Javascript stopwatch incrementing by powers of two

I have the following code for my simple stopwatch, which only counts the number of seconds with no formatting whatsoever:
function countDown(from, interval, callback) {
interval = interval || 1000;
var current = 0;
var onCount = function() {
current++;
if (current <= from) {
callback(current, from);
setInterval(onCount, interval);
}
}
onCount();
}
This is called with an onclick, with the following code:
countDown(600, 1000, function(current, from) {
time_out.innerHTML = current;
});
Putting in a console.log(current), I can see two problems. First, though it does go through every number, it seems to get faster and faster, by powers of two. In the output div, the first tick will be 1, the second will be 2, the third will be 4, the fourth will be 8, and so on. Furthermore, it does not actually stop counting when it hits 600, even though it stops updating the div. What did I do wrong here?
You use setInterval which will call the callback at a set interval every time the function is called, resulting many many calls to countDown()
Maybe you wanted to use the setTimeout function instead, which will only call the function once after the delay.

Javascript for loop and setTimeout issue

So I thought that the following code would be really simple but has become a big headache. It should be a loop that will change the opacity of and object so that it fades away.
function doSomething()
{
var i = 10;
for(i = 10; i >=0; i = i - 1)
{
setTimeout("setOpacity('t1',"+ i +")", 100*i);
WRITE 1
}
}
function setOpacity(elem, hmm)
{
WRITE 2
document.getElementById(elem).style.opacity = (10 - hmm)/10;
document.getElementById(elem).style.filter = 'alpha(opacity=' + (10 - hmm)*10 + ')';
}
So the problem is that the for loop is counting down from 10 to 0 and this has been confirmed by a print statement located at WRITE 1. However in the setOpacity method the numbers being received are starting at 0 and counting to 10 and this has been confirmed by a print statement at WRITE 2.
I would like to know why this is happening and how I can fix it. I believe it has something to do with the setTimeout call executing the method call after the end of the loop, but if that is so then why are the values being passed to setOpacity incrementing?
Any help is much appreciated.
The values being passed to setOpacity are increasing because you are passing different timeouts. The result of your loop is essentially the following:
setTimeout("setOpacity('t1', '10')", 1000)
setTimeout("setOpacity('t1', '9')", 900)
setTimeout("setOpacity('t1', '8')", 800)
....
setTimeout("setOpacity('t1', '0')", 0)
The result is that they are called in reverse order based on the timings. So the last call gets executed in 0ms (after the function finishes), resulting in 0 as hmm, followed by 1, 2, 3 ...
To fix this you need to change 100*i to 100 * (10 - i)

Categories

Resources