Checking setInterval every 5 minutes on the 0 second - javascript

const secondsInterval = () => {
const date = getNow();
if (dayjs(date).minute() % 5 !== 0 && dayjs(date).second() !== 0) {
console.log("return...");
return;
}
console.log("checking...");
...
};
// Check every second, if we're at the 5-minute interval check.
setInterval(secondsInterval, 1000);
This seems to get stuck. It's "checking" on every second of each 5 minute mark. What am I doing wrong? Thanks in advance.
Goal: To "check" every minute and 00 seconds: :00:00, :05:00, :10:00, , :15:00, etc Thanks again.

You should find out what's the time to your next rounded 5 min. like this:
const FIVE_MIN = 1000 * 60 * 5;
function waitAndDoSomething() {
const msToNextRounded5Min = FIVE_MIN - (Date.now() % FIVE_MIN);
console.log(`Waiting ${msToNextRounded5Min}ms. to next rounded 5Min.`);
setTimeout(() => {
console.log('It is now rounded 5 min');
waitAndDoSomething();
}, msToNextRounded5Min);
}
waitAndDoSomething();

If all you care about is executing some code every 5 mins, then don't have it execute every second needlessly, only to return out. Just have it run every 5 mins (300000 MS) and have it do what you need to do and remove all the checking for 5 minute mark code out its unnecessary.
const secondsInterval = () => {
// -------------------- Remove ----------------
//const date = getNow();
//if (dayjs(date).minute() % 5 !== 0 && dayjs(date).second() !== 0) {
// console.log("return...");
// return;
//}
// -------------------- Remove ----------------
console.log("checking...");
...
};
// Check every 5 mins
setInterval(secondsInterval, 300000);

Your logic for the if is screwy. Here I reversed it so the if takes care of "do the thing" and the else returns.
const secondsInterval = () => {
const date = dayjs(new Date());
if (dayjs(date).minute() % 5 == 0 && dayjs(date).second() == 0) {
console.log("checking...");
} else {
console.log("returning...");
return;
}
//...
};
// Check every second, if we're at the 5-minute interval check.
setInterval(secondsInterval, 1000);
<script src="https://unpkg.com/dayjs#1.8.21/dayjs.min.js"></script>

Related

How do I modify this code to create a loop inside a loop?

I found this script from a website. The loop ends when it has followed 40 Instagram accounts at a 2-second interval. How do I modify the script so it waits for 10 minutes before repeating the same loop for 3 times? Basically, it goes:
Follow an account and wait for 2 seconds X40
Wait for 10 minutes
Follow an account and wait for 2 seconds X40
Wait for 10 minutes
Follow an account and wait for two seconds X40
Wait for 10 minutes
---LOOP ENDS---
var TagFollow = document.getElementsByTagName("button");
var SearchFollow = "Follow";
var foundFollow;
function clickfollow(){
for (var i = 0; i < TagFollow.length; i++) {
if (TagFollow[i].textContent == SearchFollow) {
foundFollow = TagFollow[i];
foundFollow.click();
break;
}
}
}
var i = 1;
function myLoop() {
setTimeout(function() {
console.log(new Date().toLocaleTimeString());
clickfollow();
//document.getElementsByTagName("ul")[3].scrollIntoView(false
i++;
if (i < 41) {
myLoop();
}
}, 2000)
}
myLoop();
Thanks in advance!
You do not need nested loops. You can "linearize" them in single loop (I do not recall the correct therm now). So basically you want loop of 3 * 40 = 120 and after each 40 you need to use increased delay of 10 * 60 * 1000 = 600000. You help yourself by using modulo function i%40. Because you start with 1, the each 40th iteration is when remainder of i divided with 40 is zero.
So basically change if (i < 41) to if (i < 121) and }, 2000) to }, i%40 === 0 ? 600000 : 2000)

Pomodoro Timer goes negative and counts up

I have a pomodoro timer that is supposed to count down the "workminutes" a user has input and then the break minutes and then loop. The timer starts to count down WorkMinutes like it should and then break minutes(like it should), it then restarts and counts down the workminutes again like it should BUT when its done with that and it comes to the breakminutes a second time instead of counting down from eg. 1 minute it counts from -1 minute and up, so -1 minute and one second and so on. I'm a complete beginner in JavaScript so it would be very nice if you kept that in mind, any help i greatly appreciated. Here is the JavaScript code:
// we need some variables to store the work and break minutes
var workSeconds = "120", breakSeconds = "60";
// and a referens to interval
var xInterval;
var audio = new Audio('Bell_finished.mp3');
// start function
function start() {
xInterval = setInterval(workCountDown, 1000);
}
// stop function
function stop() {
clearInterval(xInterval);
}
// reset function; calls stop, save which re-stores the values of user inputs and then starts again.
function reset() {
stop();
save();
start();
}
// save function that saves the values of user inputs
function save() {
workSeconds = parseInt(document.getElementById("TaskTime").value)*60;
breakMinutes = parseInt(document.getElementById("BreakTime").value)*60;
}
// working count down function
function workCountDown() {
// counting down work seconds
workSeconds--;
// showing work seconds in "0:0" format:
document.getElementById("timer").innerText = Math.floor((workSeconds / 60)).toString() + ":" + (workSeconds % 60).toString();
// if workSeconds reaches to zero, stops the workInterval and starts the breakInterval:
if (workSeconds == 0) {
audio.play();
console.log("relaxing...");
clearInterval(xInterval);
xInterval = setInterval(breakCountDown, 1000);
}
}
// breaking count down function
function breakCountDown() {
// counting down break seconds
breakSeconds--;
// showing break seconds in "0:0" format:
document.getElementById("timer").innerText = Math.floor((breakSeconds / 60)).toString() + ":" + (breakSeconds % 60).toString();
// if breakSeconds reaches to zero, stops the breakInterval, resets the variables to initial values by calling save function and starts the workInterval again:
if (breakSeconds == 0) {
audio.play();
console.log("ready to work...");
reset();
}
}
as I said in the comment it works fine, just change breakMinutes to breakSeconds inside save function. here is an implementation of your code. you can run the snippet here and see the result
// we need some variables to store the work and break minutes
let workSeconds = "120",
breakSeconds = "60";
// and a referens to interval
let xInterval;
let isStarted = false;
// start function
function start() {
xInterval = setInterval(workCountDown, 1000);
}
// stop function
function stop() {
clearInterval(xInterval);
}
// reset function; calls stop, save which re-stores the values of user inputs and then starts again.
function reset() {
stop();
save();
start();
}
// save function that saves the values of user inputs
function save() {
workSeconds =
parseInt(document.getElementById("TaskTime").value || 120, 10) * 60;
breakSeconds =
parseInt(document.getElementById("BreakTime").value || 60, 10) * 60;
}
// working count down function
function workCountDown() {
// counting down work seconds
workSeconds--;
// showing work seconds in "0:0" format:
document.getElementById("timer").innerText =
Math.floor(workSeconds / 60).toString() +
":" +
(workSeconds % 60).toString();
// if workSeconds reaches to zero, stops the workInterval and starts the breakInterval:
if (workSeconds === 0) {
console.log("relaxing...");
clearInterval(xInterval);
xInterval = setInterval(breakCountDown, 1000);
}
}
// breaking count down function
function breakCountDown() {
// counting down break seconds
breakSeconds--;
// showing break seconds in "0:0" format:
document.getElementById("timer").innerText =
Math.floor(breakSeconds / 60).toString() +
":" +
(breakSeconds % 60).toString();
// if breakSeconds reaches to zero, stops the breakInterval, resets the variables to initial values by calling save function and starts the workInterval again:
if (breakSeconds === 0) {
console.log("ready to work...");
reset();
}
}
const startButton = document.getElementById("start-btn");
startButton.addEventListener("click", (e) => {
isStarted = !isStarted;
if (isStarted) {
save();
start();
startButton.textContent = "Stop";
} else {
stop();
startButton.textContent = "Start";
document.getElementById("timer").innerText = 0;
}
});
<label>Work Time: <input type="number" id="TaskTime" value="1" /></label>
<label>Break Time: <input type="number" id="BreakTime" value="1" /></label>
<div id="timer">0</div>
<button id="start-btn">Start</button>

JavaScript for Loop timeout

I seen this loop , and I don't understand how after the second loop ( when I = 2 ) the timeout is still 4 second and not 7 seconds.
First loop , i = 0 , x = 0 , and the output is 0 after 1 sec - i understand why
Second loop , i = 1 , x = 1 , and the output is 1 after 4 sec - i understand why 3000 X 1 + 1000 = 4000 ( 4 sec )
Third loop , i = 2 , x = 2 , the output is 2 after 4 sec - why 4 sec and not 7 ? 3000 X 2 + 1000 is 7000 ( 7 sec ) but why i get the output after 4 sec and not 7 ?
for (var i = 0; i <= 10; i++) {
(function(x) {
setTimeout(function() {
console.log(x);
}, 1000 + (3000 * x));
})(i);
}
The current execution plan is as follows:
As you can see, all the executions were relative to the starting point (almost).
If you wanted the executions to happen one after the other (0 after 1 second, 1 after 5 seconds, 2 after 12 seconds), then do this:
function compoundedInterval(x, limit) {
if (x > limit) {
return;
}
setTimeout(function() {
console.log(new Date(), x);
compoundedInterval(x + 1);
}, 1000 + (3000 * x));
}
compoundedInterval(0, 10);
I've updated the console.log to add the time so we can see the actual gaps between executions.
I now have the ff. results:
The timeout for i, x = 2 is 7 seconds. That is why it happens 3 seconds after i, x = 1 fires. This function as written does not register the next timer when the previous timer fires, it registers all 10 within a few milliseconds of being called, They go off at 4, 7, 10, 13, 16, 19, 22, 25, 28, and 31 seconds.
This one, however, will have a longer delay between each one. The key is registering the next timer as the current one is firing instead of all 10 at once.
function timeRecurse (i=0) {
var next = () => timeRecurse(i +1)
console.log(i);
return (i < 10) ? setTimeout(next, 1000 + (3000 * i)): null;
}
timeRecurse();
There is 7 seconds delay for third iteration, but from start of the script, not from second iteration. It is because of asynchronous nature of javascript.
All timeouts will start at the same time and each console output will happen 3 seconds after previous one.
Check javascript event loop for more information.
For example, this video pretty nicely explains that topic in my opinion.

Is there a way to iterate through a timer in React?

I'm trying to create a Pomodoro timer using Hooks and I have set up the basic functionality using useState and useEffect. I have a 25-minute timer that counts down and every time it gets to 0, it starts a break timer of 5 minutes. What I'm trying to figure out now is how to create an iteration that says "every 4 times the timer hits 0, change the break time from 5 minutes to 15 minutes and then, go back to 5 minutes." I thought of creating sessions that way it will say 4th session and then it will go back to 1. but I'm really not sure what to do here.
import React, { useState, useEffect } from "react";
function Pomodoro() {
const [minutes, setMinutes] = useState(25);
const [seconds, setSeconds] = useState(0);
const [displayMessage, setDisplayMessage] = useState(false);
const [session, setSession] = useState(1);
useEffect(() => {
let interval = setInterval(() => {
clearInterval(interval);
if (seconds === 0 && minutes !== 0) {
setSeconds(59);
setMinutes(minutes -1);
} else if (seconds === 0 && minutes === 0) {
let minutes = displayMessage ? 24 : 4;
let seconds = 59;
setSeconds(seconds);
setMinutes(minutes);
setDisplayMessage(!displayMessage);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
const timerMinutes = minutes < 10 ? `0${minutes}` : minutes;
const timerSeconds = seconds < 10 ? `0${seconds}` : seconds;
return (
<div className="pomodoro">
<div>Session:{session} </div>
<div className="message">
{displayMessage && <div>Break time! New Session starts in:</div>}
</div>
<div className="timer">
{timerMinutes}:{timerSeconds}
</div>
</div>
);
}
export default Pomodoro;
Your approach using a counter to keep track of the completed sessions seems to make sense. If you want to use a different amount of break time for every fourth iteration, you could use the remainder operator as below:
let breakTime = (session % 4) === 0 ? 14 : 0;
Then, you just need to make sure you are incrementing your session variable by one each time you complete a session. This also means you only want to increase it when you are not "on break" so you must make sure to guard against that.
Updating the answer with the full code that I tested to be working. Note the following changes I made:
I am only keeping track of the timer in seconds - this reduces the complexity inside useEffect and you can convert from seconds to other formats (try using the remainder operator again)
Moved the period lengths to constants
Renamed the variable displayMessage to isOnBreak for clarity
import React, { useState, useEffect } from "react";
// Define the period lengths (in seconds)
const workTime = 2;
const shortBreakTime = 4;
const longBreakTime = 6;
function Pomodoro() {
const [seconds, setSeconds] = useState(workTime);
// Renamed this variable for clarity to indicate it is a boolean
const [isOnBreak, setIsOnBreak] = useState(false);
const [session, setSession] = useState(1);
useEffect(() => {
let interval = setInterval(() => {
clearInterval(interval);
if (seconds === 0) {
let breakTime = (session % 4 === 0) ? longBreakTime : shortBreakTime;
let seconds = !isOnBreak ? breakTime : workTime;
// A session is complete when work and break is done,
// so only increment when finishing a break
if (isOnBreak) setSession(session+1);
setSeconds(seconds);
setIsOnBreak(!isOnBreak);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
// Here you could convert from seconds to minutes and seconds or whatever time format you prefer
const timerSeconds = seconds < 10 ? `0${seconds}` : seconds;
return (
<div className="pomodoro">
<div>Session:{session} </div>
<div className="message">
{isOnBreak && <div>Break time! New Session starts in:</div>}
</div>
<div className="timer">
{timerSeconds}
</div>
</div>
);
}

Change setGame text every 10 minutes

I'm trying to do something on the Discord Bot I want to change the setGame text every 10 minutes
For example, 10 minutes later, "#StayHome" => client.user.setGame(#StayHome);
or again after 10 minutes "!watch" = > client.user.setGame(!watch);
I want it to change the setGame text I want every 10 minutes. how can I do that ?
client.user.setStatus("online");
client.user.setGame(`!help`);
const bot = () => {
let status = ["!help", "!watch", "#StayHome"];
let index = 0;
let interval = setInterval(() => {
client.user.setStatus("online");
client.user.setGame(status[index]);
index++;
if (status.length === index) clearInterval(interval);
}, 1000 * 60 * 10);
};
bot();
You can use a setInterval() function and repeat it each 600000 ms (10 minutes).
let currentActivity = 0
let maxActivity = 3
setInterval(async () => {
currentActivity++;
if (currentActivity > maxActivity) {currentActivity = 0};
switch(currentActivity) {
case 0:
client.user.setStatus("online");
client.user.setGame(`!command`);
break
case 1:
client.user.setStatus("online");
client.user.setGame(`!hello`);
break
case 2:
client.user.setStatus("online");
client.user.setGame(`something`);
break
case 3:
client.user.setStatus("online");
client.user.setGame(`!help`);
break
};
}, 600000);
Using a switch statement you can change the status each 10 minutes.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

Categories