This question already has answers here:
In JavaScript, how can I access the id of setTimeout/setInterval call from inside its event function? [closed]
(2 answers)
Closed 6 years ago.
Is it possible to send interval id to executing function as an argument ? For example some thing like this:
var id= setInterval(myFunc.bind(null,id),1000);
What I am going to do is that in myFunc I want to do some processing and clear interval if I need. I can't use global variable because it will be happened multiple time. And I know that I can use global array but it would a little a bit of time consuming because of my function logic. So I want to know if I can pass interval id as an argument to myFunc.
EDIT:
this stackOverfllow link dosen't help me because there were no helpful answer.
I use this pattern:
function myFunc(host){
console.log(host.id);
}
var host = {};
host.id = setInterval(myFunc.bind(null,host),1000);
You could actually try mixing up setTimeout and setInterval to accomplish what you are looking for.
you could read more about setInterval on how to pass additional parameters to the functions.
var interval = 0;
function logId(param) {
interval++;
if (interval === 3) {
clearInterval(param);
}
console.log(param);
}
var id = setInterval(function() {
setTimeout(logId, 0, id)
}, 1000);
You can create your own function to store your callback function and interval id in the same object and pass that object to your interval function which will call the provided function with the interval id.
function setMyInterval(f,t) {
var handleMyInterval = function(ob) {
ob.func(ob.id);
};
var idOb = {func: f};
idOb.id = setInterval(handleMyInterval,t,idOb);
return idOb.id
}
You can use function inside you interval so you can do like this.
Create a function that will do interval and clear itself after a time you set.
intervalTime is time for loop interval and timeout is the time to clear interval loop.
both receive in millisecond.
function test(intervalTime,Timeout,log){
var id = setInterval(function(){
console.log(log)
},intervalTime);
setTimeout(function(){
clearInterval(id);
}, Timeout);
}
test(1000,10000,'test1');
test(1000,1000,'test2');
Related
I have a function called "showCustomer" that get number between 1-5 and return something.
I want to use setInterval, to run this function every 5 second but with another number.
Its not working, i don't understand why its not working to me. here is the code.
setInterval(function () {
var i = 1;
showCustomer(i);
i++;
}, 5000);
Just move the declaration of variable i before the setInterval() call:
var i = 1;
setInterval(function () {
showCustomer(i);
i++;
}, 5000);
The anonymous function you've set as a callback for setInterval gets called every 5 seconds in your code. In every call, you're setting i to 1 which resets it every time.
Moving i outside the setInterval callback makes it persist the the current value.
Every time you use var, you redeclare the value of that variable. So you only should declare the counter one time.
Every time that the browser calls the callback showCustomer the if statement evaluates if the browser should make a new call.
clearInvertal() it's the method to stop the setInterval() method.
var id = 1;
var show5times = window.setInterval(showCustomer, 5000);
function showCustomer() {
alert(id);
id++;
if(id > 5) {
window.clearInterval(show5times);
}
}
I need to invoke some function given number of times through given delays. How should I do - declare variable for timer and pass it to invoking function for stopping timer in some moment or in loop (n times) invoke setTimeout once ( or some another approach to skeep delay time once) or other.Thanks.
edit to fix syntax eror
var timerID = null;
var n = 5;
this.timerID = setInterval(function(){
funcToInvoke(n,timerID){
if(invokeNumber == n){
clearInterval(timerID);
return;
}
else { do something}
}
},delay)
Yes, the approach is common and better than calling setTimeout in a loop (with a fixed number of times). It is more performant than that and also more flexible, because the interval will be stopped dynamically (might check for a future condition).
However, your code is a bit messy. Fixed:
// Assuming we a have
// n
// delay
// funcToInvoke
// and execute in context of some object
var that = this,
numberOfInvokes = 0;
this.timer = setInterval(function() {
// "this" points to the global object
if (numberOfInvokes == n)
clearInterval(that.timer);
else
funcToInvoke(numberOfInvokes);
numberOfInvokes++;
}, delay);
Your current method has a syntax problem, you can't have a function parameter like this.timerID). In fact, you should remove the whole funcToInvoke declaration, and declare n and timerID as local variables, so they will be available to the closure. Like this:
// Don't forget to define n here!
var n = 5;
// Change timerID to local var instead of property
var timerID = null;
timerID = setInterval(function(){
if(invokeNumber == n){
clearInterval(timerID);
return;
} else {
//do something
}
// You can setTimeout again anywhere in this function if needed
}, delay);
If you want an approximate delay, setInterval is probably ok. If you want a more precise interval, then repeated calls to setTimeout are better as you can adjust the length of time to the next call based on the time since the last call.
E.g. for a clock ticking every second, you can do repeated calls to setTimeout, setting the lag to just after the next full second.
I have a <div> on my page that refreshes automatically every two minutes with updated log entries. When I first load my webpage, I call the following function.
function getLogs() {
var filter = $('#filter').val();
$.get("index-ajax.asp", { queryType: "getLogs", filter: filter,
uTime: new Date().getTime() },
function(data){
$("#logEntries").html(data);
window.setTimeout("getLogs()",120000);
});
}
I know the above code could be cleaner with window.setInterval(...); but I just like the control of window.setTimeout(...);.
My question, is it possible to cancel the next timeout execution? In the event that I change the filter, I'd like to cancel the next timeout, and call the function right away, which would reschedule the timeout function. Is there a better way to achieve that result?
Note that the above code is in jQuery.
Yes, use clearTimeout.
Ex:
var clr = window.setTimeout(getLogs,120000);
The when you wan to clear it:
clearTimeout(clr);
setTimeout returns a timerID that you can pass to clearTimeout:
// Note we are passing the *function* rather than a string
// Also note the lack of () - we are *not* calling the function
// setTimeout will do that for us
var timerID = setTimeout(getLogs, 120000);
// Fake condition - we cancel the timer if the timerID is even
if (timerID % 2 === 0) {
clearTimeout(timerID);
}
You could always define a new variable based on a filter value and if that filter value is set, use a while statement to omit the timeout:
if(filter == "whatevs"){
var i=true;
}
function(data){
$("#logEntries").html(data);
while(i!=true){
window.setTimeout("getLogs()",120000);
}
}
I have function called rotator(id): this function animate div and I can called this function with different id for animate different elements
Actually I use 5 differents id , 1,2,3,4,5
And for call I need put :
rotador(1);rotador(2);rotador(3);rotador(4);rotador(5);
The problem it´s that I want to rotate in automatic mode. For this I think to use this
for (i=0;i<=5;i++) {
setTimeout(rotador(i),2000);
}
But it doesn't work because it animates all in the same time, no let firt execute the first and continue before of first go second , etc , etc and when go the end or number 5 start other time in one
My problem it´s this if you can help me THANKS !!! :) Regards
You are actually calling the rodator(i) function, and schedule for execution after 2 seconds the result of the rodator. In other words, your code is now equalent to:
for (i=0;i<=5;i++) {
var result = rotador(i);
setTimeout(result,2000);
}
You can accomplish this either by creating a function for the callback:
for (i=0;i<=5;i++) {
setTimeout((function(i){
return function(){
rotador(i);
}
})(i),2000 * i);
}
or you can call the next rodator in the rotador function itself:
var rotador = function(i){
// your code
if (i < 5) {
setTimeout(function(){rotaror(i + 1);}, 2000);
}
}
Note: the closure in the second example is needed to call the function with the correct value of i. We are creating an anonymous function, and create i as a local scope variable, which value won't be mutated by the outerscope changes. (we can rename i to n in the local scope, if this would be more readable). Otherwise the value of i will be 5 each time rotador is called, as the value of i would be modified before the actual function call.
since setTimeout() does not wait for the function to be executed before continuing, you have to set the delay to a different value for different items, something like 2000 * (i + 1) instead of just 2000
EDIT: yes, and you need the callback as Darhazer suggests
rotationStep(1);
function rotador(id)
{
console.log(id);
}
function rotationStep( currentId )
{
rotador(currentId);
var nextId = currentId<5 ? currentId+1 : 1;
setTimeout(function(){ rotationStep(nextId) },2000); //anonymous function is a way to pass parameter in IE
}
Use a callback:
setTimeout(function() {
rotador(i)
}, 2000)
I need some help with a JavaScript function that I call onKeyUp, it is a Ajax function but every time I write any character it calls the function and it slow the page performance and it check every time, it is an user check with the database.
I tried this:
var timer;
function chk_me(){
clearTimeout(timer);
timer=setTimeout(function validate(){...},1000);
}
But my validate function have a parameter so I am unable to pass it, I call the function like this:
<input type="text" name="usuario" id="usuario" class="required" onKeyUp="chk_me();" minlegth="4" value=/>
Is it right? What should I do?
It is my first question and I hope that you all understand it
Thanks,
Alberto
Thank you all, since I am new I cant do it in a different answer so I edited my question with the solution.
I find this: http://bytes.com/topic/javascript/answers/451142-need-advice-acting-only-last-onkeyup-event-series and use the last answer method and add it some code, I leave you the code, like it say it isnt the best way but works so if you have some other way I will appreciate it and use it here it is:
var keyCount = 0;
var timeoutCount = 0;
function handleKeyUp() // keyup handler
{
keyCount++;
setTimeout("compareCounts()", 500);
}
function compareCounts()
{
var usuario = document.profileForm.usuario.value;
timeoutCount++;
if (keyCount == timeoutCount)
{
xajax_checaUsuario(usuario);
}
}
So I take the var in that way any suggestions to make it better?
Thanks
Don't pass validate directly to setTimeout, but rather call it from within an anonymous function:
var timer;
function chk_me(arg) {
clearTimeout(timer);
timer = setTimeout(function () {
validate(arg);
}, 1000);
}
If I understood your question correctly, I think what you want is to contain your parameter within a closure:
var timer;
function chk_me(myparam) {
clearTimeout(timer);
var validate = function() {
//do stuff with myparam
var foo = myparam;
}
timer=setTimeout(validate,1000);
}
As before, the timer ensures any previous calls are canceled, unless there's been a 1 second wait, and when you define validate within the scope of chk_me, the local variable myparam will be visible inside it, even when it's handle is passed to setTimeout.
You can do the following
var timer;
function chk_me(myparam){
clearTimeout(timer);
timer=setTimeout(function validate(){...},1000);
}
In javascript you can access any variables in the scope in which the function is defined. And below is how you use it.
<input type="text" name="usuario" id="usuario" class="required" onKeyUp="chk_me('stringval');" minlegth="4" value=/>