I have assigned 5000 ms to Settimeout but it is executing before assigned time interval.Can any body explain why it is happening.
<script type="text/javascript">
var getcallback = {
closure: function (callback, functionparam) {
return callback.call(functionparam);
}
}
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(getcallback.closure(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
},this), this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
</script>
Because getcallback.closure() is executing the function right away, you are not storing a reference to a function to call at a later time.
As soon as you call startAnimation, you're calling getcallback.closure, which immediately calls the callback function. To use setTimeout correctly, you need to either have closure return a function, or not use such a strange thing, and instead just use an anonymous function.
Something along the lines of:
var getcallback = {
closure: function (callback, functionparam) {
return function() {
callback.call(functionparam);
};
}
}
...
Or, to be cleaner, just:
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
}, this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
Related
function debounce(fn, delay) {
var timer
return function () {
var context = this
var args = arguments
clearTimeout(timer)
timer = setTimeout(function () {
fn.apply(context, args)
}, delay)
}
}
I'm curious about the purpose of context = this in this code. I don't understand the code very well.
Secondly, fn.apply (context, args) This part is also not well understood. Is there a special reason to bind this? You want to use the debounce function as an util function throughout the project.
export function debounce(fn, delay) {
var timer;
return function () {
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(this, args);
}, delay);
};
}
I want to know the difference between the last chord and the first chord
var context = this
The reason why you would put this into a different variable in this code is simply that
function(){} has a different this value based on where it gets called. In this case it's called from setTimeout as a callback, which means that this would be whatever it is inside of setTimeout instead of what it was when the debounce inner function was called
You could get around this pretty easily in modern JavaScript using arrow functions, which have a lexical this - this is based on where the function was created instead of where it is called.
This would be the equivalent code to the initial version with the correct this binding.
function debounce(fn, delay) {
var timer
return function () {
var args = arguments
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
fn.apply(context, args)
function#apply allows you to run a function with both a specific this value applied to it as well as passing in multiple arguments in an ergonomic way. Before we had rest syntax, function#apply was the only approach to this, now you can actually just use fn(...args) in modern javascript (assuming you don't have to explicitly bind the this value of the function). Just keep in mind that this is an incredibly confusing concept for nearly everyone.
The reason why you would bind context in general in the function as defined, is just so that debounce is more generic and more capable of being called in different circumstances. For example, in this case, we can use this to increment a counter based on the element that the function was called on.
In practice, you wouldn't want the same debounced function put on both, you'd want to have one function and then debounce it twice, otherwise you could end up "canceling" a click on one by clicking on the other, but it's a good example of how this can make it more functional.
function debounce(fn, delay) {
var timer
return function() {
var args = arguments
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
const debounced = debounce(function() {
this.dataset.numClicks = (Number.parseInt(this.dataset.numClicks || 0)) + 1;
this.innerText = `Clicked ${this.dataset.numClicks} Times!`
console.log(this.innerText)
}, 500);
document.querySelectorAll('button').forEach(el => el.addEventListener('click', debounced));
div {
height: 100%;
width: 100%;
color: black;
background: pink;
}
<button>Click me!</button>
<button>Click me!</button>
Pretty easy to see what the difference is when you test it out.
function debounce1(fn, delay) {
var timer
return function() {
var context = this
var args = arguments
clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(context, args)
}, delay)
}
}
function debounce2(fn, delay) {
var timer;
return function() {
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(this, args);
}, delay);
};
}
var button = document.querySelector('button');
button.addEventListener('click', debounce1(function(){console.log("1", this);}, 500));
button.addEventListener('click', debounce2(function(){console.log("2", this);}, 500));
<button>Click</button>
You maintain the context of what triggered the function vs using the window object in the timeout.
I have the following JS code:
var delay = 5000;
function init() {
setInterval(getFileCount, delay);
}
function getFileCount() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
// Do stuff with response
});
}
On page load I'm calling the init() function. The idea is to start the interval and call the getFileCount() function every 5 seconds.
So, the interval waits 5s after the page loads and runs, but it always makes the Ajax call twice.
What am I missing?
UPDATE:
I know the init() function is triggered twice on page load (thanks to the comment by Yury Tarabanko). I don't quite understand, why. The almost-full code:
$(function() {
'use strict';
function handleCourseNotification() {
var delay = 5000;
function init() {
setInterval(getFileCount, delay);
}
function getFileCount() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
updateCourseList(response.items);
});
}
function updateCourseList(items) {
// update course list...
}
return {
init: init
};
}
if ($('#js-auth-course-list').length) {
var notificationHandler = handleCourseNotification();
notificationHandler.init();
}
});
It's a small module, which I initialize after page load, if a specific element is available in the DOM - $('#js-auth-course-list'). Why is init called 2 times actually? I directly call it once.
In general, it is not a good idea to call asynchronous calls inside a setInterval() because you do not know the exact response time. So, you could end up calling the second async function before the response from the first call has returned.
You can try with setTimeout() like this:
var delay = 5000;
var async = function() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
// Do stuff with response
// Call the async function again
setTimeout(function() {
async();
}, delay);
});
}
async();
I'm assigning to a variable, a function that uses setInterval, but I don't want the function to run until I call it. However, the function is running from just the assignment statement.
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
I have also tried like this:
sayHi = function() {
console.log("Hi");
}
var sayHiStarter = setInterval(sayHi, 1000);
Both of these initiate the function and will log "Hi" to the console.
Why is it running on assignment? And what can do I do fix this?
If you only want to bind a function to setInterval, but call it later, you can use bind:
var sessionClock = setInterval.bind(null, function() {
console.log("Hi")
}, 1000);
//... later
var myInterval = sessionClock(); // start the timer
// ... later if you need to clear it
clearInterval(myInterval);
In principle, bind returns a new function that calls your original function (in this case, setInterval) with predefined arguments. So when you call sessionClock, that returned function is called. There a other aspects to bind, but they don't seem to apply in this context.
The call to setInterval does not return a function, but an identification for the created interval. This id is used to remove the interval when you don't want it to execute anymore:
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
...
clearInterval(sessionclock);
What you want is something like this:
sessionClock = function () {
return setInterval(function() {
console.log("Hi")
},
1000);
}
//When needed
var intervalId=sessionClock();
How can I use setTimeout if I want to return a value
$.each(pCodes, function(index, pCode) {
setTimeout(func(parm1), 2000);
});
function func(in)
{
var value = 999;
return value;
}
First of all, your call to setTimeout is wrong. You are calling the function func and then using the result in the setTimeout method. Your code is equivalent to:
$.each(pCodes, function(index, pCode) {
var temp = func(parm1);
setTimeout(temp, 2000);
});
As func returns 999, you will be doing setTimeout(999, 2000), which of course doesn't make sense. To call a function that takes a parameter from setTimeout you need a function that makes that function call:
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1); }, 2000);
});
To handle the return value from func is a bit more complicated. As it's called later on, you have to handle the return value later on. Usually that is done with a callback method that is called when the return value is available:
var callback = function(value) {
// Here you can use the value.
};
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback) {
var value = 999;
callback(value);
}
First of all, make sure you pass to setTimeout a function, in your example you passed undefined to it, as you func(param1) executes func directly. What you want is something like this:
setTimeout(function() { func(parm1); }, 2000);
And for 'returning' the value: Use some kind of callback function that is executed with the value when timeout expired. Like so:
function callback(value) {
// doSomethingWithNewValue
}
$.each(pCodes, function(index, pCode) {
setTimeout(function() { func(parm1, callback); }, 2000);
});
function func(in, callback)
{
var value = 999;
callback(value);
}
This is the general pattern used in such scenario (see event driven programming).
change it to :
var defValue;
$.each(pCodes, function(index, pCode) {
setTimeout(function(){defValue=func(parm1)}, 2000);
});
this way you can use the defValue in your function to access the returned value
It's pretty ugly, but you can use output parameters, since js objects are pass by reference:
function a() {
var param1 = 42;
var result = {};
b(param1, result);
}
function b(val, output) {
something();
output.returned = 4;
}
Or, you can use a callback (the better option):
function a() {
var param1 = 42;
b(param1, function (newVal) {
something();
});
}
function b(val, callback) {
//something
callback(4);
}
By the way, your call to setTimeout is wrong. setTimeout receives a function as a first parameter, and a delay as a second - the first argument is still seen as regular javascript code, so it evaluates it, so your setTimeout call turns out to be like this:
setTimeout(999, 2000);
Since you're returning 999 from the function.
However, setTimeout can also receive a list of arguments after the second parameter, so it can be turned into this:
setTimeout(func, 2000, param1);
I need to call the javascript function dynamically after some delay, The function display_1, 2, ... n will be dynamically constructed. My script looks like this, but the function never gets triggered if I use the following code, but if I hardcode the function it just seems to be fine.
function display_1() {
alert(1);
}
function display_2() {
alert(2);
}
function display() {
var prefix = 'display_';
for(var i = 1; i < 3; i++) {
setTimeout(prefix.concat(i), 1000);
}
window.onload = display();
Instead of going via a string, you may as well group the functions into an array:
function display_1() {...}
function display_2() { ... }
var functions = [ display_1, display_2 ];
function display() {
for( var i = 0; i != functions.length; ++i ) {
setTimeout( functions[i], 1000 );
}
}
If you want to go further, you may even leave out the explicit function names:
var functions = [
function() { /*the function_1 implementation*/
},
function() { /*the function_2 implementation*/
}
];
you have to add the parenthesis so that the function is called:
setTimeout(prefix.concat(i)+"()", 1000);
or simply:
setTimeout(prefix + i + "()", 1000);
Besides of that please note that both functions are called pratically at the same time, because the timers started with ´setTimeout()` start at the same time.
Depending on what you're trying to do you might have a look at setInterval() or start the second timeout at the end of the display_1() function.
It should be
function display_1() {
alert(1);
}
function display_2() {
alert(2);
}
function display() {
var prefix = 'display_';
for(var i = 1; i < 3; i++) {
setTimeout(prefix.concat(i)+'()', 1000);
}
}
window.onload = display;
the string passed to setTimeout should call the function
onload should be set to a function, not its return value
setInterval('load_testimonial()',5000);//first parameter is your function or what ever the code u want to execute, and second is time in millisecond..
this will help you to execute your function for every given time.
If you really want a 1000ms delay between executing the functions, you could do something like this:
window.onload = function() {
var n = 0;
var functions = [
function() {
alert(1);
setTimeout(functions[n++], 1000);
},
function() {
alert(2);
setTimeout(functions[n++], 1000);
},
function() {
alert(3);
}
];
setTimeout(functions[n++], 1000);
};
(rewrite it in a less-repetitive nature if needed)