Call a function max once in a sec - javascript

I have a function that is used to send messages and that is called multiple times in a sec.
But I want to call that function once a sec and delay other calls of that function with another 1-second of the previous call.
So that only that function run in the background and called once in a second, no matters how many times it is called it will delay each call to one second ahead.
For example:
function foo(a) {
console.log(a)
}
foo('one');
foo('two');
foo('three');
in the above example, foo is called three times within a sec but I want to have it called like after the 1 second it should return "one" after 2 seconds it should return 'second' and so on and it should be asynchronous.
How can I do this?
The technology I am using is Javascript.
Thanks

Well this is the first thing I came up with - perhaps it's crude.
var queuedUpCalls = [];
var currentlyProcessingCall = false;
function foo(a) {
if (currentlyProcessingCall) {
queuedUpCalls.push(a);
return;
}
currentlyProcessingCall = true;
setTimeout(function(){
console.log(a);
currentlyProcessingCall = false;
if (queuedUpCalls.length) {
var nextCallArg = queuedUpCalls.shift();
foo(nextCallArg);
}
},1000);
}
foo('one');
foo('two');
foo('three');
For each call, if you're not currently processing a call, just call setTimeout with a delay of 1000ms. If you are processing a call, save off the argument, and when the setTimeout that you kicked off finishes, process it.
Somewhat improved answer using setInterval:
var queuedUpCalls = [];
var timerId;
function foo(a) {
queuedUpCalls.push(a);
if (timerId) {
return;
}
timerId = setInterval(function(){
if (!queuedUpCalls.length) {
clearInterval(timerId);
timerId = null;
return;
}
var nextCallArg = queuedUpCalls.shift();
console.log(nextCallArg);
}, 1000);
}
foo('one');
foo('two');
foo('three');

Here is a simple queue system, it basically just pushes the functions onto an array, and then splice's them off every second.
const queue = [];
setInterval(function () {
if (!queue.length) return;
const f = queue[0];
queue.splice(0, 1);
f();
}, 1000);
function foo(a) {
queue.push(function () {
console.log(a)
});
}
foo('one');
foo('two');
foo('three');

you could use this to run the main code first and then run some more code a little later.
function firstfunction() {
alert('I am ran first');
setTimeout(function(){ alert('I am ran 3 seconds later') }, 3000);
}
<button onclick="firstfunction();">click me</button>

function foo(a)
{
if (typeof foo.last == 'undefined')
foo.last = Date.now();
var now = Date.now();
if (now - 1000 > foo.time)
foo.last = now;
setTimeout(function()
{
console.log(a);
}, (foo.last += 1000) - now);
}
This will queue each console.log call with intervals of 1 second, the first call will also be delayed by 1 second.

You could do this:
function foo() {
console.log(“ran”);
}
setInterval(foo, 1000);
In the last line, writing foo() without parenthesis is intentional. The line doesn’t work if you add parentheses.

Related

Timer: setTimeout and function call

function tick() {
seconds_lapsed++; // Break point.
}
function countdown() {
while(!stopped || !is_paused()){
setTimeout(tick, 1000); // 1 second.
show_counter();
}
}
Could you tell me why the interpreter doesn't stop at the breakpoint? The while loop works, hava a look at the screenshot.
The while loop is a "busy" loop, i.e. it keeps the JavaScript engine busy, so it will not process anything that is waiting in one of its event/job queues. This means that the user interface does not get updated, no input can be processed, and events produced by setTimeout are not consumed. In this example, tick can only get executed if the currently running code finishes. So the while loop must end first.
You should let tick execute, and only then check the condition:
var stopped = true;
var seconds_lapsed = 0;
document.querySelector("button").addEventListener("click", function() {
stopped = !stopped;
seconds_lapsed = 0;
this.textContent = stopped ? "Start" : "Stop";
if (!stopped) countdown();
});
function show_counter() {
document.querySelector("span").textContent = seconds_lapsed;
}
function is_paused() {
return document.querySelector("input").checked;
}
function tick() {
seconds_lapsed++;
}
function countdown() {
show_counter();
setTimeout(function () {
if (stopped) return; // stop the loop
if (!is_paused()) tick();
countdown(); // <--- this is the "loop"
}, 1000);
}
Seconds elapsed: <span>0</span><br>
<input type="checkbox">Paused<br>
<button>Start</button>
the following example might help you accomplish what you are after. Distinguish between setInterval() and setTimeout()
Basically the docs say:
setTimeout executes a function or specified piece of code once the timer expires.
setInterval repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
So if you use setInterval you don't need a while loop inside because it is already called "repeatedly"
var counter = $('#counter');
var stopped = false;
var seconds_lapsed=0;
var myInterval;
function tick() {
if(stopped) {
clearInterval(myInterval);
show_counter('FINISHED');
return;
}
show_counter(seconds_lapsed++);
}
function show_counter(message){
counter.html(message);
}
function countdown() {
myInterval = setInterval(tick, 1000);
}
function endCountdown(timeout) {
let timeoutId = setTimeout(function(){
stopped = true;
clearTimeout(timeoutId)
}, timeout);
}
countdown(); // start the countdown
endCountdown(5000); // ends the countdown after 5000 ms => 5sec
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="counter">counter</div>

How to autorefresh my Ajax inside of a condition [duplicate]

Using setTimeout() it is possible to launch a function at a specified time:
setTimeout(function, 60000);
But what if I would like to launch the function multiple times? Every time a time interval passes, I would like to execute the function (every 60 seconds, let's say).
If you don't care if the code within the timer may take longer than your interval, use setInterval():
setInterval(function, delay)
That fires the function passed in as first parameter over and over.
A better approach is, to use setTimeout along with a self-executing anonymous function:
(function(){
// do some stuff
setTimeout(arguments.callee, 60000);
})();
that guarantees, that the next call is not made before your code was executed. I used arguments.callee in this example as function reference. It's a better way to give the function a name and call that within setTimeout because arguments.callee is deprecated in ecmascript 5.
use the
setInterval(function, 60000);
EDIT : (In case if you want to stop the clock after it is started)
Script section
<script>
var int=self.setInterval(function, 60000);
</script>
and HTML Code
<!-- Stop Button -->
Stop
A better use of jAndy's answer to implement a polling function that polls every interval seconds, and ends after timeout seconds.
function pollFunc(fn, timeout, interval) {
var startTime = (new Date()).getTime();
interval = interval || 1000;
(function p() {
fn();
if (((new Date).getTime() - startTime ) <= timeout) {
setTimeout(p, interval);
}
})();
}
pollFunc(sendHeartBeat, 60000, 1000);
UPDATE
As per the comment, updating it for the ability of the passed function to stop the polling:
function pollFunc(fn, timeout, interval) {
var startTime = (new Date()).getTime();
interval = interval || 1000,
canPoll = true;
(function p() {
canPoll = ((new Date).getTime() - startTime ) <= timeout;
if (!fn() && canPoll) { // ensures the function exucutes
setTimeout(p, interval);
}
})();
}
pollFunc(sendHeartBeat, 60000, 1000);
function sendHeartBeat(params) {
...
...
if (receivedData) {
// no need to execute further
return true; // or false, change the IIFE inside condition accordingly.
}
}
In jQuery you can do like this.
function random_no(){
var ran=Math.random();
jQuery('#random_no_container').html(ran);
}
window.setInterval(function(){
/// call your function here
random_no();
}, 6000); // Change Interval here to test. For eg: 5000 for 5 sec
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="random_no_container">
Hello. Here you can see random numbers after every 6 sec
</div>
setInterval(fn,time)
is the method you're after.
You can simply call setTimeout at the end of the function. This will add it again to the event queue. You can use any kind of logic to vary the delay values. For example,
function multiStep() {
// do some work here
blah_blah_whatever();
var newtime = 60000;
if (!requestStop) {
setTimeout(multiStep, newtime);
}
}
Use window.setInterval(func, time).
A good example where to subscribe a setInterval(), and use a clearInterval() to stop the forever loop:
function myTimer() {
}
var timer = setInterval(myTimer, 5000);
call this line to stop the loop:
clearInterval(timer);
Call a Javascript function every 2 second continuously for 10 second.
var intervalPromise;
$scope.startTimer = function(fn, delay, timeoutTime) {
intervalPromise = $interval(function() {
fn();
var currentTime = new Date().getTime() - $scope.startTime;
if (currentTime > timeoutTime){
$interval.cancel(intervalPromise);
}
}, delay);
};
$scope.startTimer(hello, 2000, 10000);
hello(){
console.log("hello");
}
function random(number) {
return Math.floor(Math.random() * (number+1));
}
setInterval(() => {
const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';//rgb value (0-255,0-255,0-255)
document.body.style.backgroundColor = rndCol;
}, 1000);
<script src="test.js"></script>
it changes background color in every 1 second (written as 1000 in JS)
// example:
// checkEach(1000, () => {
// if(!canIDoWorkNow()) {
// return true // try again after 1 second
// }
//
// doWork()
// })
export function checkEach(milliseconds, fn) {
const timer = setInterval(
() => {
try {
const retry = fn()
if (retry !== true) {
clearInterval(timer)
}
} catch (e) {
clearInterval(timer)
throw e
}
},
milliseconds
)
}
here we console natural number 0 to ......n (next number print in console every 60 sec.) , using setInterval()
var count = 0;
function abc(){
count ++;
console.log(count);
}
setInterval(abc,60*1000);
I see that it wasn't mentioned here if you need to pass a parameter to your function on repeat setTimeout(myFunc(myVal), 60000); will cause an error of calling function before the previous call is completed.
Therefore, you can pass the parameter like
setTimeout(function () {
myFunc(myVal);
}, 60000)
For more detailed information you can see the JavaScript garden.
Hope it helps somebody.
I favour calling a function that contains a loop function that calls a setTimeout on itself at regular intervals.
function timer(interval = 1000) {
function loop(count = 1) {
console.log(count);
setTimeout(loop, interval, ++count);
}
loop();
}
timer();
There are 2 ways to call-
setInterval(function (){ functionName();}, 60000);
setInterval(functionName, 60000);
above function will call on every 60 seconds.

Execute function queue loop with timeout (javascript)

I'm facing a question here that I need to run, for example, 2 function per time, wait just 2 minutes and start run these two function again, just like a loop with a pause between the batches.
I've tried something here, and I know that my issue is, every time I start the myFunction with start function as callback I get a duplicated call. But right now, I really don't know what is the best approach to follow.
var count = 0;
function myFunction() {
console.log('function called', count);
start();
}
function batch () {
for (i = 0; i < 2; i++) {
myFunction();
console.log('batch', i);
}
console.log('--------------');
}
function start() {
console.log('started')
setTimeout(function() {
batch();
}, 2000);
count++;
}
start();
Thank you for suggestions ;)
From what I understand, you want to execute two functions every two minutes.
Have you tried using window.setInterval?
const func1 = () => console.log('func1 called');
const func2 = () => console.log('func2 called');
window.setInterval(() => {
func1();
func2();
}, 1000);
Now, func1 and func2 will be called every second.

How to run one statement after another in a procedural manner in Javascript?

Lets say we have a simple scenario where I would like to repeatedly output "Hello" followed by "World" 1 second later. I have tried the following:
setInterval(
function() {
console.log("Hello");
setTimeout(
function() {
console.log("World");
},
1000
);
},
1000
);
But it doesn't work, at the second interation of setInterval the console.log outputs Hello World at the same time.
What did I do wrong?
The outer interval should be 2 seconds.
This is not a direct answer to your question but I think its useful in your situation,
I created a queue runner function that takes a list of functions to run after a period of time
Features:
You can add as many as you want functions to the queue
You can set if you want to run the queue once or to repeat the sequence
Using only the setInterval function and without the setTimeout
Definition:
var queue = function ( /* Array<function> */ fn, /* int */ timeout, /* boolean */ repeat) {
return function () {
var i = 0,
f = fn[i],
t = setInterval(function () {
f();
if (fn[i + 1] !== undefined) {
f = fn[++i];
} else {
if (repeat) {
i = 0;
f = fn[i];
} else {
clearInterval(t);
}
}
}, timeout);
}
}
And you call it like this :
var fn = [function(){console.log('A')}, function(){console.log('B')}];
queue(fn, 1000, true)();
JSFIDDLE:
you can check the jsfiddle
Hope this help ☺

jQuery Promise with setTimeout

I need one setInterval to start after another setInterval ends. Is there a way to do this with promises?
Ideally, I would like the code to look something like this:
for (i=0; i<5; i++){
setInterval(fun_1, 1000)
//wait until this is done
}
The setInterval calls the provided function after given interval of time until you clear its object. So you do not need a loop for this. You can use a counter to terminate it after counter reaches desired value.
Live Demo.
var myInter;
i = 1;
function fun_1()
{
// some code
if(i++==5)
clearInterval(myInter);
}
myInter = setInterval(fun_1, 1000);
Do you mean that you would like the second interval to begin the countdown after the previous interval is done? In that case, you would say
window.setTimeout(fun_1, 1000);
function fun_1
{
window.setTimeout(fun_2, 1000);
}
This starts the countdown for the second timeout after the first one has completed.
You should call the next interval after the first one completes
var cnt = 0;
function executeNextStep(){
fun_1();
if (cnt<5) {
window.setTimeout(executeNextStep,1000);
}
cnt++;
}
executeNextStep(); //execute this right away
//window.setTimeout(executeNextStep,1000); use this if you want it to be delayed
if you need to execute different functions:
function fun_1() {
console.log(1);
}
function fun_2() {
console.log(2);
}
function fun_3() {
console.log(3);
}
var fnc_stack = [fun_1, fun_2, fun_3];
var cnt = 0;
function executeNextStep(){
fnc_stack[cnt]();
cnt++;
if (cnt<fnc_stack.length) {
window.setTimeout(executeNextStep,1000);
}
}
executeNextStep();

Categories