function setTimeout in loop - javascript

If I use setTimeout in a loop so only after the loop ends it executes all the operation in the same time.
I tried to put setTimeout in a separate function, as suggested by many articles, but it does not help.
The code is very simple:
function foo(i)
{
setTimeout( function() {console.log(i);}, 2000);
}
for (let i=0; i<5; i++)
{
foo(i);
}
It prints
0
1
2
3
4
in one shot

It's because the proccess registry the 5 setTimeout at almost the same time.
Try with the different timeout time like this:
function foo(i)
{
setTimeout( function() {console.log(i);}, 1000 * i);
}
for (let i=0; i<5; i++)
{
foo(i);
}

you could also do it with a generator. a generator can pause midway through a function
https://www.javascripttutorial.net/es6/javascript-generators/
function* generator() {
let index = 1;
while (index <= 5) {
yield index++;
}
}
let f = generator();
var interval = window.setInterval(function(){
const obj = f.next();
if (obj.done){
clearInterval(interval);
} else {
console.log(obj.value)
}
}, 1000);

Related

How can I print value each second in for loop JS?

I have the code:
function sleep(ms){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},ms)
});
}
let str = 'abcdef';
for(let i=0;i<str.length;i++){
sleep(1000);
console.log(str[i]);
}
How can I print str[i] each 1 second? This is code example, setInterval don't solve my problem!
let str = 'abcdef';
for(let i=0;i<str.length;i++){
setTimeout(function() {
console.log(str[i])
}, 1000 * i)
}
const str = 'mystring';
const printEveryOneSecond = (s) => {
for (let i = 0; i < s.length; i++) {
setTimeout( () =>{
console.log(s[i])
}, i * 1000)
}
}
printEveryOneSecond(str);
Using ES7, you can wrap your for loop in an async function that waits for the sleep promise to be resolved.
function sleep(ms){
return new Promise(function(resolve,reject){
setTimeout(resolve, ms)
});
}
let str = 'abcdef';
async function loop(){
for(let i = 0; i < str.length; i++) {
await sleep(1000);
console.log(str[i]);
}
}
loop()
Of course, you can make this function more flexible passing the string you want to loop over as argument.
function sleep(ms){
return new Promise(function(resolve,reject){
setTimeout(resolve, ms)
});
}
async function logSlowly(string){
for(let i = 0; i < string.length; i++) {
await sleep(1000);
console.log(string[i]);
}
}
logSlowly('abcdef')
Try to call sleep with await in front.
Like this:
await sleep(1000);
Please use the search function befor posting duplicates
here
To use the rigth functionaly please take a look to the dokumentation at this link here
I was thinking about the solution what you made. I guess what solves your issue is the following code snippet:
(function () {
let str = 'abcdef';
let timing = 0;
let printCharWithDelay = (character, timing) => {
setTimeout(function() {
console.log(character);
}, timing);
};
for(let i = 0; i < str.length; i++) {
printCharWithDelay(str[i], timing);
timing += 1000;
}
})();
I have completely restructured your code, if you run it you will have the required result.
Basically the code delays printing the passed character with the calculated milliseconds. Obviously it can be simplified but this is a good example to understand how setTimeout behaves in this scenario.
To read further about window setTimeout() method follow the link here.

javascript counter using for loop

I've created a simple counter using javascript but there is a problem Field "display" starts from 1, but it should start from 100 and goes low. The console logs shows values correctly from 100 to 1.
I have to use loops to do this tasks, so please not replace it using recursion :) Also the timeout is for sure does not equal to 100ms, it's more
function wyswietlLiczbe(j) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
}, 100);
}
for (var i= 100; i > 0; i--){
console.log(i)
wyswietlLiczbe(i);
}
<p id="display"></p>
Since the loop executes immediately, you need to wait an increasing amount of time for each number. This will queue up the innerHTML modifications.
As it is now, after a 100ms wait all 100 wyswietlLiczbe are executed in rapid succession.
function wyswietlLiczbe(j, waitTime) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
}, waitTime);
}
for (var i= 100; i > 0; i--){
console.log(i)
wyswietlLiczbe(i, (101 - i) * 100);
}
<p id="display"></p>
Build the conditional into the function which will execute after the timeout.
var elmD = document.getElementById("display");
function wyswietlLiczbe(j) {
setTimeout(function() {
elmD.innerHTML = j;
j--;
if(0 <= j ) {
wyswietlLiczbe(j)
}
}, 100);
}
wyswietlLiczbe(100);
I don't know exactly what you want but I think this is what you're looking for.
function wyswietlLiczbe(j) {
if (j >= 0) {
setTimeout(function() {
document.getElementById("display").innerHTML = j;
j--;
wyswietlLiczbe(j);
}, 100);
}
}
wyswietlLiczbe(100);
<p id="display"></p>
you can use setInterval instead
function wyswietlLiczbe(j) {
x = setInterval(function() {
if(j==0) clearInterval(x);
document.getElementById("display").innerHTML = j--;
}, 100);
}
wyswietlLiczbe(100);

javascript run function with delay inside the iteration

I want to find elements with javascript with delay. In first step I made this and it works.
function mytag() {
var elements = document.getElementsByTagName('div');
for (var i=0, im=elements.length; im>i; i++) {
if (elements[i].className ==='hi'){
alert('found');
}}
}
In the second step, I made some changes to code to put delay between iteration. I followed this link but cannot make it to work . Whats wrong?
function mytag() {
var elements = document.getElementsByTagName('div');
for (var i=0, im=elements.length; im>i; i++) {
(function(i){
setTimeout(function(){
if (elements[i].className ==='hi'){
alert('found!');
}
}, 3000 * i);
}(i));
}
}
Here's an example of how you could add asynchronousity into your lookup function:
function findElements() {
var elements = document.getElementsByTagName('div');
var index = 0;
var findNext = function() {
var element = elements[index];
index++;
if (element.className === 'hi'){
// Item found
console.log('found:'+element);
}
if (index < elements.length) {
setTimeout(findNext, 100);
}
};
findNext();
}
findElements();
http://jsbin.com/zeseguribo/1/edit?html,js,console
function sleep(milliseconds) {
var start = new Date().getTime();
while (1) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
} // sleep end
then call sleep(3000) in your loop.
Edit: This is a blocking way of delay. For async, non-blocking delay, you may use a recursive function.

Loop every five seconds in Javascript

I'm trying to write a simple loop in JS (or JQuery) that updates an image every five seconds, for a total of 15 seconds (so three loops), and then quits.
It should go like this:
Wait five seconds
Execute
Wait five seconds
Execute
Wait five seconds
Execute
Quit
But setTimeout only seems to work once.
As a test, I've tried:
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, 5000);
}
for (var i = 1; i <= 5; ++i)
doSetTimeout(i);
Does not work: http://jsfiddle.net/ubruksco/
I've also tried:
for(var i = 1; i <= 5; i++) {
(function(index) {
setTimeout(function() { alert(index); }, 5000);
})(i);
}
Does not work: http://jsfiddle.net/Ljr9fq88/
var time = 1;
var interval = setInterval(function() {
if (time <= 3) {
alert(time);
time++;
}
else {
clearInterval(interval);
}
}, 5000);
you can simply create an interval and kill it after the 3rd time
Your first example is nearly there. You just need to multiply the time delay by the loop index to get the right delay.
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, 5000*i);
}
for (var i = 1; i <= 3; ++i)
doSetTimeout(i);
http://jsfiddle.net/ubruksco/3/
The reason is that your settimeout ends all at the same time (after 5 seconds) because your timeout code is based on 5 seconds
for(var i = 1; i <= 5; i++) {
(function(index) {
setTimeout(function() { alert(index); }, 5000);
})(i);
}
What you want to do is change the timeout time based on your index (hence will have different start times.
for(var i = 0; i < 3; i++) {
(function(index) {
setTimeout(function() { alert(index); }, index*5000);
})(i);
}
(Also needs 3 iterations, so edited out the loop for you)
You want setInterval() instead
setInterval(function(){ alert("Do Something"); }, 3000);
Make it easy! You do not need loop, you just need three executions.
setTimeout(function() { alert(1); }, 5000);
setTimeout(function() { alert(2); }, 10000);
setTimeout(function() { alert(3); }, 15000);
But, if you really want a loop:
function doSetTimeout(i) {
setTimeout(function() { alert(i); }, i*5000);
}
for (var i = 1; i <= 3; ++i)
doSetTimeout(i);
Assuming your are using jQuery (to manipulate the DOM),
you can try this:
['img1.jpg', 'img2.jpg', 'img3.jpg'].forEach(function(imgPath, index) {
// the callback will be executed in 5seconds * (index + 1)
setTimeout(function() {
// change image source
$('img#myImage').attr('src', imgPath);
}, 5000 * (index + 1));
});
With setTimeout:
function doSetTimeout(i) {
if(i >= 3) return;
alert(i);
setTimeout((function () {
return function () {
doSetTimeout(i);
};
})(i + 1), 5000);
}
doSetTimeout(0);
But you can also use setInterval, maybe more appropriate.
You can use setInterval instead and track how much times you have executed function. Than just use clearInterval() to stop execution.
var i = 1;
var interval = setInterval(function() {
execute();
}, 5000);
$(document).ready(function() {
execute();
});
function execute() {
$("#output").append("set<br/>");
if (i == 3) {
clearInterval(interval);
}
i++;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='output'></div>
If you want to first wait 5 secs, don't call execute() on domready.

Set a delay (timeout) inside a double (nested) loop

Completely stuck.
I have seen this popular solution for adding delays between iterations of a loop (https://stackoverflow.com/a/3583740), but it only seems to work for a single loop (i.e not nested).
This is the pseudo code,
for (var i = 0; i < max; i++){
for (var j = 0; j < max; j++){
pause(1000); // ideally would just elegantly pause all execution
}
}
I am trying to use setTimeout (unless other options exist!) but I can't seem to wrap my head around how to set it up.
Context - It should pause long enough for an animation to occur. (A different animation occurs depending on the values of i and j ).
As it has been said, you can't really pause execution in javascript. Though a trick could be to collect the instructions in a delayed queue which executes itself fifo. E.g.:
// helper function
var delayed = (function() {
var queue = [];
function processQueue() {
if (queue.length > 0) {
setTimeout(function () {
queue.shift().cb();
processQueue();
}, queue[0].delay);
}
}
return function delayed(delay, cb) {
queue.push({ delay: delay, cb: cb });
if (queue.length === 1) {
processQueue();
}
};
}());
your example, rewritten:
var i = 0, j, max = 3;
for (; i < max; i += 1) {
for (j = 0; j < max; j += 1) {
// add function to the queue, shadowing i/j with an IIFE:
delayed(1000, function(i, j) {
return function() {
console.log(i, j);
};
}(i, j));
}
}
demo: http://jsbin.com/kadepage/1/
This will work as nested for loop with delay.
var i = o = 0;
var max = 10;
var delay = 1000;
function rec()
{
console.log("outerloop"+o);
var inner = setInterval(function(){
console.log("innerloop"+i);
console.log(new Date());
i++;
if(i==max)
{
clearTimeout(inner);
var outer = setTimeout(function(){
o++;
i=0;
if(o==max)
{
return;
}
clearTimeout(outer);
rec();
},delay);
}
},delay);
}
rec();

Categories