This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 2 years ago.
Trying to make a react native app that takes text as input and converts it to morse code, using the phone's torch. I can get the translated morse code but when I try to convert that to light using the torch, the loop only runs once (There is a short flash) and then exits. Why is that happening/how do I fix that?
var j;
for(j = 0; j < cipher.length; j++) {
if(cipher[j] == '.') {
Torch.switchState(true);
setTimeout(function(){Torch.switchState(false)},200);
setTimeout(function(){},200);
}
else if(cipher[j] == '-') {
Torch.switchState(true);
setTimeout(function(){Torch.switchState(false)},600);
setTimeout(function(){},200);
}
else if(cipher[j] == ' ') {
setTimeout(function(){},600);
}
else {
setTimeout(function(){},1400);
}
}
The setTimeout() function needs a callback function to work. I guess that if you put the "if" conditionals into the callback functions it will work. I'll leave a example down here:
HTML:
<p>Live Example</p>
<button onclick="delayedAlert();">Show an alert box after two seconds</button>
<p></p>
<button onclick="clearAlert();">Cancel alert before it happens</button>
Javascript:
var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(window.alert, 2*1000, 'That was really slow!');
}
function clearAlert() {
window.clearTimeout(timeoutID);
}
Another possibility is to use an anonymous function to call your callback, but this solution is a bit more expensive. Example:
var intervalID = setTimeout(function() { myFunc('one', 'two', 'three'); }, 1000);
Checkout the Official Guides in: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
Related
This question already has answers here:
Stop for loop using break on click
(5 answers)
Closed 5 months ago.
I want my program to generate a random number and multiply it with a number that a user inputs. Then take the result and multiply that with the user inputted number. This part works but how do I stop the loop with a button?
The loop is inside of a function and I want to use a button to stop the for loop. I used setTimeout to delay each result by 1.5 seconds. I tried to use set Interval on the function start but that didn't seem to work.
Here is an example using a recursive setTimeout pattern. It's not very pretty but should be enough for you to work on:
var stopLoop = false;
function start(i) {
stopLoop = false;
loop(i);
}
function stop() {
stopLoop = true;
}
function loop(i) {
if (stopLoop) {
stopLoop = false;
} else {
setTimeout(function() {
doWork(i);
});
}
}
function doWork(i) {
document.getElementById("display").innerHTML = i++;
loop(i);
}
<button onclick="start(0);">
Start Loop
</button>
<button onclick="stop();">
Stop Loop
</button>
<div id="display"></div>
This question already has answers here:
How to wait until an element exists?
(26 answers)
How to execute javascript code after an element is created without jquery?
(2 answers)
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 1 year ago.
I am interacting with the webpage through chrome extension. I want to wait until an element (like a popup) comes up before continuing the interaction. I want to stop the execution of the function until the element appears because I am doing interacting in a sequential flow.
Below is the example function I created. This function is not working as intended. It only delays the first iteration of the loop and the rest of the iterations of the loop are instant. So, the max time this function wait is 100ms as of now. How can I either fix this function or define an elegant way to wait.
function waitUntilElementLoad(elem, maxWaitInSec) {
for (let i = 0; i < maxWaitInSec *10; i++) {
if(elem) { return true;}
setTimeout(() => {console.log(i);}, 100);
}
return false;
}
Attempt2: (Following up on comments and answers)
async function waitUntilElementLoad(elem, maxWait) {
for (let i = 0; i < maxWait*10; i++) {
if(elem) { return true;}
console.log(i);
await timer(100); // then the created Promise can be awaited
}
return false;
}
if (await waitUntilElementLoad(popUpElemNextButton, 5)) {
console.log("Popup button appeared")
} else {
console.log("Popup button not appeared")
}
The waitUntilElementLoad function returns false even if the elements load up in 1 sec and the waiting time is 5 sec. If the element is already there before calling the function. it returns true. Could it be that the function does not receive updated DOM during its processing? Is there a way to handle this?
Instead of using a loop, just call setTimeout when the element is not found.
function waitUntilElementLoad(selector, delay) {
if(document.querySelector(selector) != null){
// element found; do something
} else setTimeout(()=>waitUntilElementLoad(selector, delay), delay);
}
This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 6 years ago.
how to fix this code as per
How do I add a delay in a JavaScript loop?.
it still gets executed without delay .
const spkz = responsiveVoice.speak;
let azj = ['hi', 'hello', 'how are ya'];
var i = 1; // set your counter to 1
function myLoop() { // create a loop function
azj.forEach((item, index) => {
setTimeout(() => { // call a 3s setTimeout when the loop is called
alert(item); // your code here
i++; // increment the counter
if (i < index) { // if the counter < 10, call the loop function
myLoop(); // .. again which will trigger another
} // .. setTimeout()
}, 10000)
})
}
myLoop();
You can't "pause" javascript like that. a setTimout is asynchronous, meaning it will not block synchronous code from running, so when you run any kind of "for" loop, it will call all the setTimeouts at once.
You can make a manual loop like this and delay it with recursion:
let azj = ['hi', 'hello', 'how are ya'];
var i = 0;
function myLoop() {
setTimeout(function() {
console.log(azj[i])
i++
if (i < azj.length) {
myLoop()
}
}, 3000)
}
myLoop();
For more information, check out this answer.
You don't have to use forEach inside the loop function. Instead, you can access the array items using azj[i]
This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
Closed 8 years ago.
i'm writing a code and i've stuck with setTimeout function. I would like to get animation effect. Display elements of array with delay. Code is done.
for (var i=0;i <= array.length-1;i++) {
(function(el) {
setTimeout(function(){
document.getElementById('Result').innerHTML += Math.floor(el);
console.log(Math.floor(el));
}, 3000*(i+1));
})(array[i]);
I had problem with delay when i use for (var i=array.length-1; i>=0;i--) Why? (The idea of this code is display items array form the last to the first)
for (var i=0;i <= array.length-1;i++) {
(function(el) {
setTimeout(function(){
Give now the same resultat as: for (var i=array.length-1; i>=0;i--) {
console.log(array[i]+'!')
The problem here is about closures. A closure is a type of anonymous function used to remember the arguments for using them later in asynchronous code (e.g. in functions called by setTimeout).
If you write something like:
setTimeout(function(foo){...}(value), 3000)
the function gets called before calling setTimeout. You have to use a closure to do this:
(function(foo){
setTimeout(function() {
... do something with foo ...
}, 3000);
})(value_of_foo);
This code will remember the value of foo creating a setTimeout with a function that uses it.
Another problem is that you have to increase the setTimeout time to create a delay, otherwise the for will create a bunch of setTimeout(..., 3000) that will be executed all at once. So what you will need to do to your code is something like the following:
for (var i = 0; i <= array.length; i++) {
(function(el) {
setTimeout(function(){
document.getElementById('Result').innerHTML += Math.floor(el)
}, 3000 * i);
})(array[i]);
}
Timeouts don't execute until after your main function has finished, this means that by the time your timeout function executes per loop, your i variable will be at its final value (in this case = 0). Your function declaration is also incorrect as the timeout function does not pass in those parameters for you. To do this, you need to wrap your timeout inside of another function call that takes in the parameters for the current loop, try something like this instead...
for (var i=array.length-1; i>=0;i--) {
function(array, i) {
setTimeout(function() {
document.getElementById('Result').innerHTML += Math.floor(array[i]);
}, (i+1) * 3000);
}(array, i);
}
First of all you are immediately calling the function and its result is assigned as the callback of the timeout. (this is wrong as the first argument must be a function)
Then, you have some syntax errors with missing closing } and )..
Try
for (var i=array.length-1; i>=0;i--) {
function(array,i){
setTimeout(function(){
document.getElementById('Result').innerHTML += Math.floor(array[i]);
}, 3000*i);
}(array,i);
}
I used 3000*i so that each timeout is 3 seconds after the other
This question already has answers here:
All the setTimeouts inside javascript for loop happen at once
(2 answers)
Closed 10 years ago.
I searched around and found some others with similar issues, but I can't seem to find a solution or clear explanation.
var content = 'test<br />';
for( var i = 1; i < 6; i++ ) {
setTimeout(function() {
document.write(content);
}, 3000);
}
I'd like the code in the for loop to execute 5 times, with a three second delay between each loop. When it runs it, at least on the surface, looks like a three second delay at page load, then goes through all the loops with no delay.
What am I missing?
Your problem is that all the calls are happening after 3000 ms. Do perform each call 3s apart do this:
var content = 'test<br />';
for( var i = 1; i < 6; i++ ) {
setTimeout(function() {
document.write(content);
}, 3000 * i);
}
You probably need to use setInterval ('cause you're trying to run code at a certain "interval")
// first create an isolated namespace because we don't need to dirty the global ns //
(function(){
var counter = 0;
var maxIterations = 6;
var intervalReference = setInterval(function(){
// your code goes here //
alert('test');
// the stop condition //
++counter;
if (counter == maxIterations) {
clearInterval(intervalReference);
}
}, 3000);
}())
setInterval is probably the way to go (see Alin's answer) but if you were wanting to go down the setTimeout route, the code would look something like this:
var loop = 0;
var content = "test<br>";
function startTimeout(init){
if(init!==true){
document.write(content);
loop++;
}
if(loop<5){
setTimeout(startTimeout, 3000);
}
}
startTimeout(true);