I run a script in the browser that scrolls the page down. I run it from the browser console (ctrl + shift + j).
var popWys = 0;
var terazWys = 0;
var proba = 0;
function scrollowanie() {
if(popWys == document.body.scrollHeight)
{
proba++;
if(proba > 10)
{
window.alert("To juz chyba wszystko, w razie czego odpal ponownie.");
return;
}
}
else
{
proba = 0;
}
popWys = document.body.scrollTop;
terazWys += 1000;
window.scrollTo(0,terazWys);
setTimeout(scrollowanie, 100);
}
setTimeout(scrollowanie, 100);
Question. How to stop it at any time from the command line? Can I write something, press to stop? Sam will never stop and blocks the browser. I tried with different: return; break; Stop. anything and nothing works.
Can it be done at all?
You can use clearTimeout([variable name]) to stop the setTimeout(scrollowanie, 100);
Just assign setTimeout(scrollowanie, 100); to global variable like following:
globalVar = setTimeout(scrollowanie, 100);
And in the console type clearTimeout(globalVar) and the execution will finish
You could wrap desired behaviour in an object that handles the process.
e.g.:
var script = (function () {
var timeout;
var DESIRED_TIME = 100;
function scrollowanie() {
console.log('::Testing');
// Desired behaviour here
clearTimeout(timeout);
timeout = setTimeout(scrollowanie, DESIRED_TIME)
}
return {
start: function() {
timeout = setTimeout(scrollowanie, DESIRED_TIME);
},
stop: function () {
clearTimeout(timeout);
}
}
})();
Then in the command line you will just need to start the process
script.start();
and to end it
script.stop();
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;
}
}
Here is the code I am using. When ticks becomes equal to 5 the recursion function should stop clearing the mainThread timeout. Anybody please help.
var mainThread;
var ticks = 0;
function tickTimer() {
clearTimeout(mainThread);
if (ticks >= 5) {
endGame();
}
else {
mainThread = setTimeout(function () {
ticks++;
tickTimer();
}, 1000);
}
}
Let me know if any concerns.
Thank you in advance.
Try this instead:
function tickTimer() {
if (++ticks >= 5) {
clearInterval (mainThread);
endGame();
}
}
var mainThread = setInterval(tickTimer, 1000);
var ticks = 0;
you can try this. all you need to do is clear interval every time tickTimer function is called.
var mainThread = setInterval(tickTimer, 1000);
var ticks = 0;
function tickTimer() {
if (++ticks >= 5) {
clearInterval (mainThread);
endGame();
}
}
Did you declare mainThread ? Like this
var mainThread = null;
function tickTimer() {
clearTimeout(mainThread);
mainThread = null;
if (ticks >= 5) {
endGame();
}
else {
mainThread = setTimeout(function () {
ticks++;
tickTimer();
}, 1000);
}
}
And ticks++ not ticks--
Please try to replace ticks-- to ticks++
I've think just send your timer as argument
function tickTimer(timer) {
timer && clearTimeout(timer);
if (ticks >= 5) {
endGame();
}
else {
var timer = setTimeout(function () {
ticks--;
tickTimer(timer);
}, 1000);
}
}
Don't use global scope )))
I thing you should Initialize variable ticks as the function is triggered.
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.
I'm trying to build a loading indicator with a image sprite and I came up with this function
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
so the out put is looks like this
http://jsfiddle.net/TTkre/
I had to use setBgPosition(); inside else to keep this running in a loop so now my problem is how to stop this loop once I want [load finished]?
setTimeout returns a timer handle, which you can use to stop the timeout with clearTimeout.
So for instance:
function setBgPosition() {
var c = 0,
timer = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
timer = setTimeout(run, 200);
}
timer = setTimeout(run, 200);
return stop;
function stop() {
if (timer) {
clearTimeout(timer);
timer = 0;
}
}
So you'd use that as:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
Note that rather than having setBgPosition call itself again, I've just had it set c back to 0. Otherwise, this wouldn't work. Also note that I've used 0 as a handle value for when the timeout isn't pending; 0 isn't a valid return value from setTimeout so it makes a handy flag.
This is also one of the (few) places I think you'd be better off with setInterval rather than setTimeout. setInterval repeats. So:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c >= numbers.length) {
c = 0;
}
}
return setInterval(run, 200);
}
Used like this:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
All of the above notwithstanding, I'd want to find a way to make setBgPosition stop things itself, by detecting that some completion condition has been satisfied.
I know this is an old question, I'd like to post my approach anyway. This way you don't have to handle the 0 trick that T. J. Crowder expained.
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
SIMPLIEST WAY TO HANDLE TIMEOUT LOOP
function myFunc (terminator = false) {
if(terminator) {
clearTimeout(timeOutVar);
} else {
// do something
timeOutVar = setTimeout(function(){myFunc();}, 1000);
}
}
myFunc(true); // -> start loop
myFunc(false); // -> end loop
You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.
var done = false;
function setBgPosition() {
if ( done ) return;
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
if ( done ) return;
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
setBgPosition(); // start the loop
setTimeout( function(){ done = true; }, 5000 ); // external event to stop loop
var myVar = null;
if(myVar)
clearTimeout(myVar);
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
Try something like this in case you want to stop the loop from inside the function:
let timer = setInterval(function(){
// Have some code to do something
if(/*someStopCondition*/){
clearInterval(timer)
}
},1000);
You can also wrap this inside a another function, just make sure you have a timer variable and use clearInterval(theTimerVariable) to stop the loop
As this is tagged with the extjs tag it may be worth looking at the extjs method: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:
function setBgPosition() {
var c = 0;
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run() {
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<numbers.length){
c=0;
}
}
return Ext.Function.interval(run,200);
}
var bgPositionTimer = setBgPosition();
when you want to stop you can use clearInterval to stop it
clearInterval(bgPositionTimer);
An example use case would be:
Ext.Ajax.request({
url: 'example.json',
success: function(response, opts) {
clearInterval(bgPositionTimer);
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
clearInterval(bgPositionTimer);
}
});
I am not sure, but might be what you want:
var c = 0;
function setBgPosition()
{
var numbers = [0, -120, -240, -360, -480, -600, -720];
function run()
{
Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px');
if (c<=numbers.length)
{
setTimeout(run, 200);
}
else
{
Ext.get('common-spinner').setStyle('background-position', numbers[0] + 'px 0px');
}
}
setTimeout(run, 200);
}
setBgPosition();
In the top answer, I think the if (timer) statement has been mistakenly placed within the stop() function call. It should instead be placed within the run() function call like if (timer) timer = setTimeout(run, 200). This prevents future setTimeout statements from being run right after stop() is called.
EDIT 2: The top answer is CORRECT for synchronous function calls. If you want to make async function calls, then use mine instead.
Given below is an example with what I think is the correct way (feel to correct me if I am wrong since I haven't yet tested this):
const runSetTimeoutsAtIntervals = () => {
const timeout = 1000 // setTimeout interval
let runFutureSetTimeouts // Flag that is set based on which cycle continues or ends
const runTimeout = async() => {
await asyncCall() // Now even if stopRunSetTimeoutsAtIntervals() is called while this is running, the cycle will stop
if (runFutureSetTimeouts) runFutureSetTimeouts = setTimeout(runTimeout, timeout)
}
const stopRunSetTimeoutsAtIntervals = () => {
clearTimeout(runFutureSetTimeouts)
runFutureSetTimeouts = false
}
runFutureSetTimeouts = setTimeout(runTimeout, timeout) // Set flag to true and start the cycle
return stopRunSetTimeoutsAtIntervals
}
// You would use the above function like follows.
const stopRunSetTimeoutsAtIntervals = runSetTimeoutsAtIntervals() // Start cycle
stopRunSetTimeoutsAtIntervals() // Stop cycle
EDIT 1: This has been tested and works as expected.
When the task is completed and you can display the task (image in your case), on the next refresh don't send the javascript. If your server is using PHP.
<?php if (!$taskCompleted) { ?>
<script language="javascript">
setTimeout(function(){
window.location.reload(1);
}, 5000);
</script>
<?php } ?>