I want to call a method 5 times in every one second. for example I have a methodA which i want to execute this method in 5 times in every 1 second. so how can i do it.
methodA(){
console.log("called")
}
timePeriod(){
setimeout....
}
You can do it with setInterval()
const test = setInterval(() => console.log("Hello method"),1000);
setTimeout( () => clearInterval(test), 5000);
Hope it is what you need!
let timePeriod = 1000 // 1000 ms
function methodA(){
console.log("called")
}
setInterval(methodA, timePeriod)
notice here that we pass the function as an argument without () which in other words we're referencing the function. Note that if you pass the function name along with () it means you're calling it independently
Also, keep in mind that setInterval works a little bit different than you might think as it's a macro task asynchronous function in the event loop. if you don't know about the event loop simply all you need to know that setInterval doesn't actually call the function unless the rest of you script gets fired + the time period you specify
setInterval = the time needed to fire the rest of the script + the time period you specify
and what you can do to test this is:
const tick = Date.now(), timeLog = (val='---') => console.log(`${val} \n Elapsed: ${Date.now() - tick} ms`)
setInterval(_ => timeLog('smth from setInterval'), 1000)
for(let i=1;i<1000000000;i++){
// this loop will run for 1B times so that we get a clear time delay
}
timeLog('smth from normal console.log')
const Comp= () => {
const methodA=()=>{
// statement here
}
useEffect(()=>{
let a = setInterval(methodA,1000/5)
return(()=>{
clearInterval(a)
},[])
})
return(<></>)
}
Try to use interval inside useEffect hook.
One could control both, the interval itself and also the condition for terminating the running interval, by writing a utility/helper function which enables not only clocked functions but also clocked methods.
function clocked(interval, isTerminate, proceed, target) {
let count = 0;
let intervalId = setInterval(() => {
proceed.call(target ?? null);
if (isTerminate(++count)) {
clearInterval(intervalId);
}
}, interval);
}
const obj = {
text: "The quick brown fox jumps over the lazy dog.",
log() {
console.log(this.text);
},
};
function doTerminateWhen(counter) {
return counter >= 5;
}
setTimeout(() => { console.log('1.001 seconds passed'); }, 1001);
clocked(200, doTerminateWhen, obj.log, obj);
setTimeout(() => { console.log('1 second passed'); }, 1000);
.as-console-wrapper { min-height: 100%!important; top: 0; }
setInterval is being used her to call the methodA function at each once second and modCall function has a for loop to iterate and call the setInterval the number of times specified in its paramter
function methodA(i){
console.log('call '+i)
}
function modCall(len){
for(let i=0;i<len;i++){
setInterval(()=>methodA(i),1000)
}
}
modCall(5) //5 is number of time you want to call the methodA
Related
I've a doubt in one output question.
Expectation -> I need to print numbers in a range (from , to) at every 1 second gap. I need to implement this in both ways setTimeout & setInterval. (Question link)
I've made 3 methods -
printNumbers(from ,to) -> Using setTimeout or setInterval, it is not working fine (My doubt is in this method, Why it is not taking gap of 1 second)
printNumbersT(from ,to) -> Using setTimeout, it is working fine
printNumbersI(from ,to) -> Using setInterval, it is working fine
printNumbers(from ,to) is printing all numbers at same time without a gap of 1 second. I want to know how is this working, why it is not taking a gap of 1 second. I need explanation for this.
// ❌ not working fine (My doubt is in this method, Why it is not taking gap of 1 second)
const printNumbers = (from, to) => {
for (let i = from; i < to; i++) {
setInterval(() => console.log(i), 1000);
}
}; //
// ✅ working fine
const printNumbersT = (from, to) => {
let current = from;
const fun = () => {
console.log(current);
if (current < to) {
current++;
setTimeout(fun, 1000);
}
};
setTimeout(fun, 1000);
};
// ✅ working fine
const printNumbersI = (from, to) => {
let current = from;
const fun = () => {
console.log(current);
if (current < to) {
current++;
} else {
clearInterval(timerId);
}
};
const timerId = setInterval(fun, 1000);
};
code snippet
setInterval and setTimeout are asynchronous, as said in mdn
setTimeout() is an asynchronous function, meaning that the timer function will not pause execution of other functions in the functions stack. In other words, you cannot use setTimeout() to create a "pause" before the next function in the function stack fires.
In your for loop you are adding synchronously n function calls to the end of the stack, so they will be fired aproximately at the same time.
To fix this you could use a promise and await its return, or you can change the delay.
const printNumbers = (from, to) => {
for (let i = from; i < to; i++) {
setTimeout(() => console.log(i), 1000 * i);
}
};
I'm trying to figure out how to set time out for function inside the loop iteration in Ionic TypeScript application.
setInterval makes equal time interval with calling the function in endless repetition:
setInterval(() => {
this.myFunc1(val);
}, 800);
setTimeout gives required result if listed sequentially:
setTimeout(() => {
this.myFunc1(val);
}, 800);
setTimeout(() => {
this.myFunc1(val);
}, 1200);
but how to loop with time interval trough the updated list and wait while pass second value val to the function, or call myFunc1 when it will be finished in previous iteration:
async myFunc2() {
for (let val of this.myValueList) {
/// wait for 5 sec or wait for finishing process, then pass value calling function:
this.myFunc1(val);
}
}
setInterval is the correct choice here. What's missing is that you need to clear the interval. setInterval returns an id that you can pass to clearInterval which stops the iteration.
Here I'm passing data to console.log, waiting a second, then repeating till done.
const myValueList = [5,6,7,8,9,10];
let i = 0;
const id = setInterval(() => {
console.log(myValueList[i++]);
if (i === myValueList.length) {
clearInterval(id);
console.log("done!");
}
}, 1000);
Simplest solution for waiting approximately 5 seconds:
const wait = t => new Promise(r => setTimeout(r, t));
and then in your code you can just do:
async myFunc2() {
for (let val of this.myValueList) {
await wait(5000);
this.myFunc1(val);
}
}
If myFunc1 is async, and you just want to wait for it to finish executing before continuing the loop, then you would just do:
async myFunc2() {
for (let val of this.myValueList) {
await this.myFunc1(val);
}
}
I am trying to return a function that only invokes a callback function 'func' once per every 'wait' milliseconds.
Additional calls to the callback 'func' within the 'wait' period should NOT be invoked or queued.
This is what I have so far...
function throttle(func, wait) {
function inner(...args) {
setInterval(func(...args), wait);
}
return inner;
}
When I run the code through the test algorithm I get the following errors:
"throttled functions should only be able to be called again after the specified time"
Here is the testing algorithm...
let counter = 0;
const incr = () => counter++;
const throttledIncr = throttle(incr, 32);
throttledIncr();
throttledIncr();
setTimeout(() => {
expect(counter).to.eql(1);
throttledIncr();
setTimeout(() => {
expect(counter).to.eql(2);
done();
}, 32);
}, 32);
"throttled functions return their value"
Here is the testing algorithm...
let counter = 0;
const incr = () => ++counter;
const throttledIncr = throttle(incr, 32);
const result = throttledIncr();
setTimeout(() => {
expect(result).to.eql(1);
expect(counter).to.eql(1);
done();
}, 64);
"throttled functions called repeatedly should adhere to time limitations"
Here is the testing algorithm...
const incr = () => ++counter;
const throttledIncr = throttle(incr, 64);
const results = [];
const saveResult = () => results.push(throttledIncr());
saveResult();
saveResult();
setTimeout(saveResult, 32);
setTimeout(saveResult, 80);
setTimeout(saveResult, 96);
setTimeout(saveResult, 180);
setTimeout(() => {
expect(results[0]).to.eql(1);
expect(results[1]).to.be(undefined);
expect(results[2]).to.be(undefined);
expect(results[3]).to.eql(2);
expect(results[4]).to.be(undefined);
expect(results[5]).to.eql(3);
done();
}, 192);
My questions regarding each case:
How do I prevent the function from being called again ?
Why ISNT my function returning value? I can't deduce what or how to return a value with the given testing algorithm.
What does "throttled functions called repeatedly should adhere to time limitations" even mean? This seems contradictory to the first error. There isn't any mention of setting a time limit so I don't believe using setTimeout here is what they mean...
How do I prevent the function from being called again ?
function throttle(func, wait) {
function inner(...args) {
setInterval(func(...args), wait);
}
return inner;
}
First, your code above does not do what you expect it to do. Currently every time you invoke throttle, you are adding func to the event loop, to be executed on an interval.
So when you call throttleIncr 5 times, you are adding incr to the eventloop to be called five times.
One approach (imo), would be to keep track of the last time that throttle(func) was invoked. The next time throttle(func) is invoked, check to see if the wait time has elapsed. If so, invoke func and save off the new time. If not, return.
Why ISNT my function returning value? I can't deduce what or how to return a value with the given testing algorithm.
Your incr function, IS returning the value, however your throttle function puts it on the eventloop, for asychronous execution, so the return value is not available.
What does "throttled functions called repeatedly should adhere to time limitations" even mean? This seems contradictory to the first error.
This is not a javascript error, and likely a custom failure message from the tests you are invoking.
I tried something here, that seems to be working:
function throttle2(callback, delay = 1000) {
let interval;
let currentArgs;
return (...args) => {
currentArgs = args;
if (!interval) {
interval = setInterval(() => {
if (currentArgs) {
callback(...currentArgs);
currentArgs = null;
} else {
clearInterval(interval);
interval = false;
}
}, delay);
}
};
}
Sandbox: https://codesandbox.io/s/competent-tereshkova-ccop2e?file=/index.js:167-179
In my application development, I am using
setInterval(function() {
// some code
// runs here
}, 60000);
I want to execute some code on 1 minute interval and my code may take 2-3 minutes in some cases.
<execute code> - <wait 1 minute> - <execute code> - <wait 1 minute> ......so on
I tried with setInterval function but noticed that setInterval does not wait for inner code to complete. Please suggest how can i achieve this in javascript.
Thanks
A better way may be to recursively call your job function with setTimeout:
setTimeout(function jobThatRunEveryMinute() {
// run code here that may take more than one minute
someExpensiveCodeToRun()
// start another job after someExpensiveCode completes
setTimeout(jobThatRunEveryMinute, 60000);
}, 60000);
Something like this might work for you, but why do you have a function that takes over 1 min to return something?
let callCompleted = true;
setInterval(function() {
if (callCompleted) {
callCompleted = false;
// pass a call back function to update the callCompleted to true
myLongRunningFunction(function() { callCompleted = true } );
// or if `myLongRunningFunction` returns a promise
myLongRunningFunction.then(() => { callCompleted = true } );
}
}, 60000);
// adjust wait time to your liking
const waitTime = 10000
let time = 0
// so you can stop it
const totalTime = 6
function excuteCode() {
time++;
console.log(time); // <=== replace with your inner code
if (time < totalTime) {
setTimeout(() => {
excuteCode()
}, waitTime)
}
}
excuteCode();
I saw the following code:
class MasterControlPanel {
private sensors: Sensor[] = [];
constructor() {
// Instantiating the delegate HeatSensor
this.sensors.push(new HeatSensor(this));
}
start() {
for (var i= 0; i < this.sensors.length; i++) {
// Calling the delegate
this.sensors[i].check();
}
window.setTimeout(() => this.start(), 1000);
}
startAlarm(message: string) {
console.log('Alarm! ' + message);
}
}
var cp = new MasterControlPanel();
cp.start();
Why window.setTimeout(() => this.start(), 1000); doesn't introduce infinite loop?
Based on my understanding, cp.start() will first iterate each sensor inside sensors and then call the window.setTimeout which in turn calls the start again after 1 second delay.
Reference: Listing 3-3. Delegation in Pro TypeScript: Application-Scale JavaScript Development
In short, it doesn't introduce an infinite loop because setTimeout doesn't block. Instead, the function you give it to execute, () => this.start() is added to a queue and executed after 1 second of time passes. The start method returns after calling window.setTimeout, and thus doesn't cause an infinite loop in the imperative sense. Most of the time, the code will be in a state of waiting until the next timer comes up.
That the code infinitely schedules a timer to call the start method is also true, but it isn't an infinite loop because it returns control to the javascript runtime.
It does introduce an infinite loop, delayed 1 sec between each call
window.setTimeout(() => this.start(), 1000);
is almost the same as
var _this = this;
window.setTimeout(function(){ _this.start(); }, 1000);
it's called Arrow Function
Maybe you need setInterval.
That one would create a infinite loop which you can clear by using clearInterval.
this.interval = window.setInterval(() => {
...
}, 5000);
window.clearInterval(this.interval);
Also you can do
this.sensors.forEach(sensor => sensor.check())
Instead of using for loop.
You can't use this in the setTimeout, because it refers to the setTimeout, not to your class.
Try this :
class MasterControlPanel {
private sensors: Sensor[] = [];
constructor() {
// Instantiating the delegate HeatSensor
this.sensors.push(new HeatSensor(this));
}
var that = this;
start() {
for (var i= 0; i < this.sensors.length; i++) {
// Calling the delegate
this.sensors[i].check();
}
window.setTimeout(() => that.start(), 1000);
}
startAlarm(message: string) {
console.log('Alarm! ' + message);
}
}
var cp = new MasterControlPanel();
cp.start();