setTimeout doesn't seem to be calling the function - javascript

The code worked great until I added the setTimeout. Now, no matter how I attempt to call the functions in setTimeout ( setTimeout(function(){fadeOut()},1000); setTimeout("fadeOut()",1000); etc ) it doesn't seem to get to the function at all.
I'm a Javascript newbie so any and all help is appreciated =]
javascript code:
var slideArray = ["slide1","slide2","slide3","slide4","slide5","slide6"];
var currentSlide = null;
var current = null;
var done = false;
function fade(newSlide)
{
if(currentSlide === null)
{
currentSlide = slideArray[0];
document.getElementById(currentSlide).style.opacity = 1.0;
for(var i=1;i<slideArray.length;i++)
document.getElementById(slideArray[i]).style.opacity = 0.0;
}
current = document.getElementById(currentSlide);
done = false;
do
{
window.setTimeout(fadeOut,1000);
} while(done == false);
currentSlide = newSlide;
current = document.getElementById(currentSlide);
done = false;
do
{
window.setTimeout(fadeIn,1000);
} while(done == false);
}
function fadeOut()
{
if(parseFloat(current.style.opacity)-0.1>.0000001)
{
current.style.opacity = parseFloat(current.style.opacity) -0.1;
done = false;
}
else
{
current.style.opacity = 0.0;
done = true;
}
}
function fadeIn()
{
if(0.9-parseFloat(current.style.opacity)>.0000001)
{
current.style.opacity = parseFloat(current.style.opacity)+0.1;
done = false;
}
else
{
current.style.opacity = 1.0;
done = true;
}
}

You can't use this structure:
do
{
window.setTimeout(fadeIn,1000);
} while(done == false);
Because the code in the setTimeout() runs sometime LATER, your value of done will NEVER be changed and this loop will run forever. And, as long as it runs, the setTimeout() never gets to fire either (because javascript is single threaded).
Instead, what you should do is launch the next setTimeout(fadeIn, 1000) from the fadeIn() function if you aren't done.
function fadeOut()
{
if(parseFloat(current.style.opacity)-0.1>.0000001)
{
current.style.opacity = parseFloat(current.style.opacity) -0.1;
setTimeout(fadeOut, 1000);
}
else
{
current.style.opacity = 0.0;
}
}

Remember that javascript is single-threaded, so your setTimeout'et functions will not be called until it is finished running the current script. Which will never happen since you're in a loop that's never gonna end (untill you're out of memory from all those setTimeout's). Just call setTimeout once and let the function return. And forget the idea of waiting for it to have happened.

Related

Place parts of a for loop into function in javascript

I have several functions that use this given for loop below.
function startClaw(dir){
var readCount = 0;
for(var isRead in qdata){
readCount++;
if(qdata[isRead]['reading'] == true){
return;
}else if(readCount == 5){
isAnimating = $("#claw").is(':animated');
if(!isAnimating){// prevents multiple clicks during animation
if(isMoving || isDropping){ return; }
MCI = setInterval(function(){ moveClaw(dir); },10);
//console.log("startClaw:" + dir);
stopSwingClaw();
}
}
}
}
//.................................................................
function dropClaw(){
var readCount = 0;
for(var isRead in qdata){
readCount++;
if(qdata[isRead]['reading'] == true){
return;
}else if(readCount == 5){
if(isDropping){ return; } //prevent multiple clicks
stopSwingClaw();
isDropping = true;
MCI = setInterval(moveDown,20); //start heartbeat
}
}
}
Everything in the else if statement is different within the various functions. I'm wondering if there is any way to place the "pieces" of the for loop on the outside of the else if into its very own function. I feel like I've seen this or had done this a very long time ago, but it escapes me and I couldn't find any examples. Thanks everyone!
Previewing, I see this is similar to the above. Two differences (it looks like) are here the count gets passed to the function in case they needed to ever have different checks in the if statement, and, it's checking what the return value is since it looks like you return out of the loop if the condition is met. There are notes in comments in the code below.
function startClaw(dir) {
// Pass a function as a callback to the method which expects to receive the count as a param
doReadCount(qdata, function(theCount) {
if (theCount === 5) {
isAnimating = $("#claw").is(':animated');
if (!isAnimating) { // prevents multiple clicks during animation
if (isMoving || isDropping) {
return true;
}
MCI = setInterval(function() { moveClaw(dir); }, 10);
//console.log("startClaw:" + dir);
stopSwingClaw();
}
return false;
});
}
//.................................................................
function dropClaw() {
// Pass a function as a callback to the method which expects to receive the count as a param
doReadCount(qdata, function(theCount) {
if (theCount === 5) {
if (isDropping) {
return;
} //prevent multiple clicks
stopSwingClaw();
isDropping = true;
MCI = setInterval(moveDown,20); //start heartbeat
}
});
}
function doReadCount(qdata, elseFunction) {
var readCount = 0;
var elseReturn;
for (var isRead in qdata) {
readCount++;
if (qdata[isRead]['reading'] == true) {
return;
} else {
// call the function that was sent and pass it the current read count. If the return is true, then also return true here
elseReturn = elseFunction(readCount);
if (elseReturn) {
return;
}
}
}
}
You can pass a function into another function to achieve this. I've done it for dropClaw, and it should be clear from my example how to do also extract startClaw.
function operateClaw(func){
var readCount = 0;
for(var isRead in qdata){
readCount++;
if(qdata[isRead]['reading'] == true){
return;
}else if(readCount == 5){
func();
}
}
}
function drop () {
if(isDropping){ return; } //prevent multiple clicks
stopSwingClaw();
isDropping = true;
MCI = setInterval(moveDown,20); //start heartbeat
}
function dropClaw () {
operateClaw(drop);
}

how to add a delay in a while loop. JavaScript

function falling()
{
isFalling = true;
while (isFalling == true)
{
if (y < 120) {
y++;
}
else if (y == 120) {
isFalling = false;
}
}
}
I have tried adding setTimeout(function() around the entire loop, around the if statement, around the y++. I don't know what i'm doing wrong. Any time I add any of these the page becomes unresponsive once the falling function is called. I'm well aware that this is probably a duplicate question but the duplicate questions failed ti help.
{ }, 100)
You would do it like this:
function falling(y) {
if (y < 120) {
setTimeout(falling.bind(this, y + 1), 100); // specify your delay.
}
}
falling(0);
The question has indeed been answered several times, and the answers here are really not that different from this.
Note that I removed the apparently global variable isFalling. If you do need that variable in other code, then you can keep that variable updated as follows:
function falling(y) {
isFalling = y < 120;
if (isFalling) {
setTimeout(falling.bind(this, y + 1), 100); // specify your delay.
}
}
I would use window.setInterval() instead, as you want it to repeat until a certain number
working plunkr:
https://plnkr.co/edit/TbpplnIShiaJR7sHDUjP?p=preview
function falling()
{
var isFalling = true;
var y=0;
myInterval = window.setInterval(function() {
y++;
console.log(y);
if (y== 120) {
clearInterval(myInterval);
}
}, 100)
}
falling();
If the intent of calling falling() is to temporarily set the value of a global variable to true (as suggested by your current code), then this should do the trick.
var isFalling = false;
function falling(fallDuration) {
isFalling = true;
console.log("now falling");
setTimeout(function(){
isFalling = false;
console.log("landed");
}, fallDuration || 1000);
}
falling();
I imagine though that you might actually want to fall and then continue doing something else. In that case you probably want to look at a callback or into promises. You might do a simple:
var isFalling = false;
function falling(fallDuration, andThen) {
isFalling = true;
console.log("now falling");
setTimeout(function() {
isFalling = false;
console.log("landed");
andThen();
}, fallDuration);
}
falling(1000, function(){ console.log("now standing"); });

clearInterval doesn't working

var started = false;
function start() {
var timer;
if(started === false) {
timer = setInterval(decrease, 1000);
started = true;
} else {
clearInterval(timer);
console.log("Should Clear");
}
}
The setInterval works but when I run the function again, it prints in the console that it should be removed. But it doesn't.
timer is declared inside your function, so when you call it again, it's a new instance.
Try declaring it outside the function, like this:
var started = false;
var timer;
function start() {
if(started === false) {
timer = setInterval(decrease, 1000);
started = true;
} else {
clearInterval(timer);
console.log("Should Clear");
}
}
timer gets reinitialized every time you call start so the second time you call it, it's not pointing to a timer id to clear.
use like this
var started = false;
var timer;
function start() {
if(started === false) {
timer = setInterval(decrease, 1000);
started = true;
} else {
clearInterval(timer);
console.log("Should Clear");
}
}
Because timer is in the scope of the function. So when you call it the second time, it is in another scope.

how to use setTimeout or setInterval properly

I am using google maps and i am trying to put a pause in execution to prevent QUERY_LIMIT usage issue. My function that plots the addresses looks like this.
The code works, however i want to try setTimeout or setInterval to see if its going to look better on UI.
How do i call it, what should be the first argument?
Thanx alot.
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
//geocode "free" usage limit is 5 requests per second
//setTimeout(PlotAddressesAsUnAssigned, 1000);
//sleep(500);
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
Doing a pause (asynchronous execution) inside a loop (synchronous) will usually result in a lot of trouble.
You can use recursive calls that are done only when a timeout ends.
var vLocations = [];
// Manages the timeout and recursive calls
function AddWaypointAndUnassignedWithPause(index){
setTimeout(function(){
// When the timeout expires, we process the data, and start the next timeout
AddWaypointAndUnassigned(vAddresses[index]);
// Some other code you want to execute
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
if(index < vAddresses.length-1)
AddWaypointAndUnassignedWithPause(++index);
}, 1000);
}
// Start the loop
AddWaypointAndUnassignedWithPause(0);
JSFiddle example.
Try this, hope this will help
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
setTimeout(function(){
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
}, 500);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
What about a waiting line, thats fired when an item is added and stopped when there are no items left.
With setTimeout:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startTimeout();
}
function startTimeout() {
if( to === null ) {
to = setTimout(processLocation, INTERVAL);
}
}
function processLocation() {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
to = setTimout(processLocation, INTERVAL);
} else {
to = null;
}
}
With setInterval:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startInterval();
}
function startInterval() {
if( to === null ) {
to = setInterval(processLocation, INTERVAL);
}
}
function processLocation(cb) {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
} else
clearInterval(to);
to = null;
}
}

Tap event firing X times a second in jquery

I'm trying to make touch controls for a little game I'm writting with the help of jquery. But i just can't figure out how to write a function that basicly does the same thing that happens when you keep a key pressed.
Could you please help me?
PS. its not originaly my code source
jQuery.fn.mousehold = function(timeout, f) {
if (timeout && typeof timeout == 'function') {
f = timeout;
timeout = 100;
}
if (f && typeof f == 'function') {
var timer = 0;
var fireStep = 0;
return this.each(function() {
jQuery(this).mousedown(function() {
fireStep = 1;
var ctr = 0;
var t = this;
timer = setInterval(function() {
ctr++;
f.call(t, ctr);
fireStep = 2;
}, timeout);
})
clearMousehold = function() {
clearInterval(timer);
if (fireStep == 1) f.call(this, 1);
fireStep = 0;
}
jQuery(this).mouseout(clearMousehold);
jQuery(this).mouseup(clearMousehold);
})
}
}
$.fn.extend({
disableSelection: function() {
this.each(function() {
this.onselectstart = function() {
return false;
};
this.unselectable = "on";
$(this).css('-moz-user-select', 'none');
$(this).css('-webkit-user-select', 'none');
});
}
});
Well the question is, how often do you want to check for a change in user input. You are quite limited when it comes to the resolution of a timer in JS. Although be aware that everything is running in sequence and thus events are queued and potentially sum up. This is especially true for setInterval() as it rigorously queues new events, even when previously triggered events were not yet processed.
Something like this works:
var pressed; // flag for continous press between mousedown and timer-events
var duration; // number of times the timer fired for a continous mousedown
var timeout; // reference to timer-event used to reset the timer on mouseup
$(document).mousedown = function(){
pressed = true;
handleMousedown(false);
}
function handleMousedown(continued){
if(pressed){ // if still pressed
if(continued){ // and fired by the timer
duration++;
// measure time, use duration
// do anything
}
timeout = setTimeout('handleMousedown(true)', 100); // wait for another 100ms then repeat
}
}
$(document).mouseup = function() {
// do sth on mouseup
pressed = false; // reset flag for continous mousedown
clearTimeout(timeout); // abandon the timer
}
$(document).mouseout = function() { // $(document).mouseenter = function(){
// do sth on mouse leave or mouse entering again according to how your game should behave
pressed = false; // reset flag for continous mousedown
clearTimeout(timeout); // abandon the timer
}

Categories