Javascript setTimeout give another timeout - javascript

I have a trouble with setTimeout function in javascript, my purpose is to give timeout for each insert statement, after reach given maxrecord, it will pause for 2 hours, then continue the insert statement.
Right now im only make a work for first condition wich is given delay for each insert. But i dont know how to give 2 hour delay before continue to insert.
my code like this,
var ids = $("#listId").val().split('\n');
var index = 1;
for(var i = 0; i < ids.length; i++) {
(function(i){
setTimeout(function(){
if (index <= interval) {
console.log("INDEX : " + index + " INTERVAL : " + interval);
} else {
console.log("SHOULD BREAK FOR 2 HOURS (NOTHING TODO HERE, JUST DELAY) THEN CONTINUE FROM LAST IDS");
}
index++;
}, 1000 * i);
}(i));
}
as you can see, i need to give 2 hour's delay after index <= interval and then continue again with last i.
Appreciate your help.

You are setting all of your timeouts at once, at the start, with predefined durations.
You cannot (easily) go on to modify how those times are set based on an arbitrary condition (this 2 hour delay you speak of)
Instead, you should do something like:
function nextRow() {
// handle a single row
i++;
if( i < ids.length) setTimeout(nextRow,delay);
// where delay is either 1000 or 7200000 as needed
}
nextRow(); // start the loop

Related

Count how many times document.hasFocus returns "true", if it's equal or greater than 15 do something

I'm using setInterval to check every second for document.hasFocus(), so every second it returns true or false.
setInterval(function() {
console.log(document.hasFocus());
}, 1000);
When the return of true is equal to or greater than 15, I would like to do something. I wrote the code below (which obviously doesn't work) to make it easier to understand what I want to achieve.
if (document.hasFocus()) ≥ 15 {
do something
}
Could anyone help me with this?
document.hasFocus() returns a boolean not a number.
So you can use a counter and increment it each time document.hasFocus() returns true.
Then you can test the counter.
As far as I can see, you just want to count for 15 times before calling some function or executing some logic, the variable that is responsible for counting represents your application state. So we will call it count
let count = 0;
then we just increment count while the condition is met every second, until finally we stop the interval when the condition is met
let intervalToken = setInterval(function checkDocument(){
if(document.hasFocus()){
count = count + 1;
if(count > 15){
clearInterval(intervalToken); // stop intervale here
callMyFunction(); // call your function here
}
}
}, 1000)
Simply add a counter like this:
let counter = 0;
if (document.hasFocus() && ++counter >= 15) {
alert('you did it!');
}
You just need a variable to count the number of times document.hasFocus().
let focusCount = 0;
setInterval(() => {
focusCount = document.hasFocus() ? focusCount + 1 : focusCount;
if (focusCount >= 15) {
console.log(focusCount);
}
}, 1000);

Creating a Countdown with JavaScript

I am trying to make a Countdown that just log in the terminal the seconds remaining. It should be an interval of 1 second between every log. It has to be as a method of an object. I don´t know if it's because of the scope but somehow it's not working after many trials and code-rewriting.
Anybody can help me with this?
var Countdown = function(seconds) {
this.counter = seconds;
this.start = function() {
setTimeout(
function() {
while (this.counter >= 0) {
console.log(this.counter);
this.counter -= 1;
}
},1000)
}
}
I would use a setInterval() for a simple countdown timer. I would also write my function for the math loop outside of the setInterval and then call on the function within the interval, like the following => setInterval(timerFunction(), 1000). There is no need for a loop when you use the interval, it does the looping each defined time increment as set in your setInterval(). Each time the interval fires, the function will do its thing.
EDIT: added a conditional to see if the interval time has run out.
I have included an example of a simple count down timer in my answer below along with notation inside the code that helps to explain further. Hope this helps.
Also, by terminal, I assume you mean the console? My example displays the setInterval in the console...
let sMin = 2; // amount of minutes you wish to start with
let time = sMin * 60; // format for minutes by multiplying by 60 as we have 60 seconds in each minute
let countdown = setInterval(update, 1000) // set up a setInterval for the countdown function
// create a function that will countdown the seconds
function update() {
// define our minutes using Math.floor(time / 60)
let min = Math.floor(time / 60);
// define our seconds by modulating time with 60, our seconds units
let sec = time % 60;
// tenerary conditional to see if seconds is set to 0 for proper display of formatting as seconds
sec = sec < 10 ? '0' + sec : sec;
// display the countdown timer in time format using the minutes and seconds variables
console.log(`${min}:${sec}`);
// decrement time by one second with each interval as set in the setInterval call `1000`
time--;
// clear the interval if the minutes and seconds are both set to 0
min == 0 && sec == 0 ? clearInterval(countdown) : countdown;
}
Yes it was because of the scope. As you are using this inside setTimeout() it uses the global scope.
var Countdown = function(seconds) {
this.counter = seconds;
this.start = function() {
setTimeout(
function() {
while (this.counter >= 0) {
console.log(this.counter);
this.counter -= 1;
}
}.bind(this),1000)
}
}
I'm using bind to set "this" to current context.
And with reference to your question about timeout, instead of using setTimeout() use setInterval() to achieve your need about log with respect to seconds
function countDown(whileCountingDown, forHowLong, whenFinishedThen){
//error handling begin(for user's understanding)
if(arguments.length<3){return RangeError("ALL three arguments must be used")}
var typeErrors=[]
if(typeof whileCountingDown!="function"){typeErrors.push("whileCountingDown MUST be a function")}
if(typeof forHowLong!="number"){typeErrors.push("forHowLong MUST be a number(and it represents seconds)")}
if(typeof whenFinishedThen!="function"){typeErrors.push("whenFinishedThen MUST be a function")}
if(typeErrors.length>0){return TypeError(`There are ${typeErrors.length} parameters that are incorrect data types\n\n${typeErrors.join('\n')}`)}
//error handling begin(for user's understanding)
//........................................................................................................................
//the part that matters to you once you enter correct stuff
var i=setInterval(()=>{forHowLong--
if(forHowLong<=0){//count finished, determine what happens next
clearInterval(i); whenFinishedThen()
}
else{whileCountingDown(forHowLong)}//do this for each second of countdown
},1000)
}
console.log("The timers in the console and on the html element are 2 DIFFERENT countdowns")
//example use
countDown((m)=>{console.log(`${m} seconds left`)}, 30, ()=>{console.log('Cheers, the countdown is OVER')})
//obviously you can do stuff like edit randomHTML-Element.innerText for each second of the countdown or anything as you so desire since what i made is kindof flexible
//..........................................................................................................................
//more examples
//now for some fun stuff, we're gonna be editing an html structure, but first, we're going to make a 'timeParse' function to make it look kind of elegant
function timeParse(seconds){
//yup, error handling begin
if(typeof seconds!="number"){return TypeError("The parameter 'seconds' MUST be a number")}
//yup, error handling end
//below is the stuff to look at
var timeArr=[seconds]
if(timeArr[0]>=60){//if seconds >= 1 minute
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=60){//if minutes >= 1 hour
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=24){//if hours >= 1 day
timeArr.unshift(`${Math.floor(timeArr[0]/24)}d`)
timeArr[1]=timeArr[1]%24
}
}
}
return(timeArr.join`:`)
}
//now for applying countDown to things other than the console
function countDownAgain(){//just something that will show the flexibility of what i made.. im going above and beyond because i wanna look back on my answers as notes on how to do things(also ez copy pasting for future me xD)
countDown(
(s)=>{document.getElementById('toTime').innerText="Second Count "+timeParse(s)},
86401,
()=>{document.getElementById('toTime').innerText="No way you waited that long LOL"}
)
}
countDown(
(s)=>{document.getElementById('toTime').innerText="First Count "+timeParse(s)},
100,
countDownAgain
)
<div style="background-color:red;height:100px;text-align:center;line-height:50px"><h1 id="toTime">Count Down Time :}</h1></div>

Infinite While loop mod 3

I basically just want to print numbers a list of numbers a skip multiples of 3. I got it to work but the initial way i tried it did not work and i do not understand why, just need someone to please explain why it doesn't work and goes into an infinite loop.
This is the problem, why does it go into an infinite loop? I am clearly missing a key concept about code, if someone could help thanks.
var i = 0;
while (i <= 10) {
if (i % 3 == 0) {
continue;
}
document.write( i + "</br>");
i++;
}
I know you can do it this way.
while (i <= 10)
{
if (i % 3 != 0) {
document.write("Number is " + i + "<br />");
}
i++
}
If we ignore the code producing the output and look only at the code checking and modifying i, it might become a little more clear why it's not working. It also helps to format our code for extra clarity.
var i = 0;
while (i <= 10) {
if (i % 3 == 0) {
continue;
}
i++;
}
Start with i = 0.
i <= 10 is true. Enter the loop.
i % 3 == 0 is true. Enter the if block.
continue;. Go straight to the top of the while loop again. Do not pass i++;. Do not collect 1.
Lather. Rinse. Repeat (infinitely).
continue jumps to the next iteration and doesnt complete the rest of your code in the while. So i is not being incremented but rather staying as 0 becuase you wrote continue before incrementing the i. so therefore it is in an endless loop, it is always less than 10

Skip a setInterval every X loop?

I have a function that gets triggered every 10 seconds with a setInterval(); loop, and I'd like it to skip a call every 60 seconds. So the function would be executed at 10s, 20s, 30s, 40s and 50s but wouldn't be called at 60s, then gets called at 70s and so on.
Is there any straightforward way to do this, or do I have to tinker with incrementing a variable?
Thanks!
Do like this, use the simple modulo math and a counter.
var count = 0;
var interval = setInterval(function(){
count += 1;
if(count % 6 !== 0) {
// your code
}
}, 10000);

Run a function as far as a variable reaches specific values

I have a canvas game which calls a function incScore every time an action is performed in the game to increase the score.
Inside incScore I have a few if statements to draw a particular image to represent a level number on the canvas.
I also want to have a sound play once per level up. The way I've gone about things the lvlup sound will play every time the score matches the if statement.
Can anyone please help me get this so that the sound will only play once when the level changes and not again until the next level change? I'm also mention I'm using jQuery incase it has anything that could help me.
incScore(); //everytime an action in the game causes the score to increase
function incScore(){
if (scoreTotal < 500){
lvlimg = "L01";
drawLevel(lvlimg);
lvlupSound();
}
else if (scoreTotal > 500 && scoreTotal < 1000){
lvlimg = "L02";
drawLevel(lvlimg);
lvlupSound();
}
else{
lvlimg = "L03";
drawLevel(lvlimg);
lvlupSound();
}
}
You could shorten your function and use a semi static property to save the state. Using that, you can compare the current level to the previous and play a sound if they differ.
function incScore(){
incScore.level = incScore.level || 'L0'; //< initialize property
lvlimg = "L0" + scoreTotal < 500 ? 1 : scoreTotal < 1000 ? 2 : 3;
drawLevel(lvlimg);
if (incScore.level!=='L0' &&
incScore.level !== lvlimg) { lvlupSound(); };
// ^compare local level to current
incScore.level = lvlimg;
// ^ update local level
}
[edit, based on comment] The third line is a so called ternary, or conditional operator. See MDN. You can use more conditions.
To avoid playing a sound before the score has reached a first level, you could use
if (incScore.level!=='L0' && incScore.level !== lvlimg).
I've created a mockup jsFiddle
A simple solution could be comparing the current level to the old one, to detect when the level changed:
function scoreToLevel(score)
if(score < 500){
return 1
}else if (score < 1000){
return 2
}else{
return 3
}
}
function incScore()
var next_level = scoreToLevel(scoreTotal)
if(next_level !== current_level){
lvlimg = "L0" + next_level;
drawLevel(lvlimg)
lvlupSound()
}
}
The easiest solution is to factor the sound out of those if statements. If the levels are nice and regular like that(every 500 points) and the points always increase in a way that you will always land exactly on an even multiple of 500 when you level up, something like this should do:
if(scoreTotal % 500 === 0 && scoreTotal < 1001)
{
lvlupSound();
}
If you won't always land directly on the gate to the next level(maybe the player can earn anywhere between 1 and 15 points at a time) then you should be able to get by using something along the lines of this before you increment the player's score:
if( (scoreTotal % 500) > ((scoreTotal + increment) % 500)
{
lvlupSound();
}
if your level boundries are not regular like that obviously it gets a little bit more complex, but that should get you started.
That is because you have the in every statement for every score (which means from 0 to infinite).
You will need to write inner if statements such as;
if (scoreTotal < 500){
lvlimg = "L01";
drawLevel(lvlimg);
if(scoreTotal x times of each the level) // That means for each level completed
{
lvlupSound();
}
}
If your score increment is only 1, then only play the tone when the score equals the threshold for a new level.
If they can increase their score by more than 1, then you could pass the number of points in and check the score before and after to see if the numbers fall on each side of the threshold.
If that still doesn't work, some more info on the "level" and points would be appreciated.
Try something like this (demo):
var scoreTotal,
lastLevel = 0,
levels = [500, 1000, 2500, 5000, 10000, 25000, 50000, 75000],
currentLevel = 0,
lvlImg;
function incScore() {
while (scoreTotal > levels[currentLevel]) {
currentLevel++;
}
if (lastLevel !== currentLevel) {
lastLevel = currentLevel;
// gives a two digit number with a leading zero
lvlImg = ('0' + currentLevel).slice(-2);
drawLevel("L" + lvlimg);
lvlupSound();
}
}
Then you can easily add additional levels by adding the score cutoff to the levels variable.

Categories