Javascript for цикл с задержкой

Вывод чисел в цикле с задержкой

Нужно в цикле сделать вывод чисел от 0 до 400 . Отсчёт вывожу на экран, но отображаются только 0 и 400 . setInterval прошу не предлагать. Пытался сделать с задержкой:

// Тут переменной amount назначил элемент for (var i = 0; i

2 ответа 2

Добро пожаловать в асинхронное программирование.

  • Проблема в том, что все итерации цикла происходят в одно и то же время (с точностью до пары миллисекунд).
  • Функция называется setTimeout , а не settimeout .
  • Свойство называется innerHTML , а не innerHtml .
  • В данной ситуации проще всего использовать setInterval , так как каждая итерация происходит достаточно быстро (меньше задержки между итерациями). Но раз уж вы почему-то не хотите его использовать.
  • Идея состоит в том, чтобы следующую итерацию вызывать только после завершения предыдущей, используя функцию.
document.addEventListener('DOMContentLoaded', onDomReady); function onDomReady() < var amount = document.getElementById('amount'); (function iterate(i) < amount.innerHTML = i + " фантик(ов) из 400"; if (i < 400) < setTimeout(function() < iterate(i + 1); >, 10); > >)(0); >

@СлаваГесто да, в случае запросов к серверу вариант с setTimeout более чем оправдан. Если бы вы об этом упомянули в вопросе, то я бы даже заикаться о setInterval не стал. Ответ вас устраивает?

@СлаваГесто это вызов этой функции и передача 0 в качестве значения для i . Можно убрать скобки и написать в строке ниже iterate(0); — будет тот же результат. Пример.

Топикстартер пожалуй затронул САМУЮ распространенную задачку на собеседованиях js-программиста. Вот в этом посте: habrahabr.ru/post/231071 в комментариях соревнуются кто решит ее большим числом способов, любопытно посмотреть)

Читайте также:  Echo html elements in php

Менее гибкий, менее хитрый вариант:

const amount = document.createElement('div') document.body.appendChild(amount) for(let i = 1; i< amount.innerHTML = message >, i*10) >

Связанные

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.7.27.43548

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

How to create pause or delay in FOR loop?

You cannot «pause» JavaScript in a web browser. You can, however, setup timers and cause code to be executed at a later point with the setTimeout() and setInterval() APIs available in all browsers.

tldr: You have to convert the code to recursive, continuation passing style if you want to take advantage of asynchonicity. (Well, that or use a clever trick like Guffa did)

14 Answers 14

You can’t use a delay in the function, because then the change that you do to the element would not show up until you exit the function.

Use the setTimeout to run pieces of code at a later time:

var s = document.getElementById("div1"); for (i = 0; i < 10; i++) < // create a closure to preserve the value of "i" (function(i)< window.setTimeout(function()< s.innerHTML = s.innerHTML + i.toString(); >, i * 2000); >(i)); > 

I’m a bit confused, if the closure «preserves the value of i » why isn’t what’s calculated by i * 2000 equal to 0 as 0 is the first value of i ? Or, if i is being incremented on each iteration, why is the duration between each innerHTML update not increased likewise?

it is even more confusing when I log at the first line of the loop and the first line of the iife: they both log` 0-9` immediately. i know it has been a long time, but can you explain a bit what is going on here? jsbin.com/foqineciva/edit?html,js,output

var wonderfulFunction = function(i) < var s = document.getElementById("div1"); //you could pass this element as a parameter as well i = i || 0; if(i < 10) < s.innerHTML = s.innerHTML + i.toString(); i++; //create a pause of 2 seconds. setTimeout(function() < wonderfulFunction(i) >, 2000); > > //first call wonderfulFunction(); //or wonderfulFunction(0); 

You can’t pause javascript code, the whole language is made to work with events, the solution I provided let’s you execute the function with some delay, but the execution never stops.

This will have a big problem because all the timeout funtions share the same «i» value. They’ll all pass 11 to «wonderfulFunction».

What’s the for loop for? Given it always executes the break wouldn’t it be more straightforward to use an if statement? For the same reason, I don’t see why you need the inner function.

@nnnnnn Because I edited the answer without thinking. I took a different approach at first an then I changed it to use the clousure. The way is written the for is useless, edit time :).

@VictorResnov it means «assign i to itself if the value of i is truthy, otherwise assign it to 0» developer.mozilla.org/en-US/docs/Glossary/Truthy

I tried all one, but I think this code is better one, it is very simple code.

var s = document.getElementById("div1"); var i = 0; setInterval(function () , 2000); 

if you want to create pause or delay in FOR loop,the only real method is

the startTime is the time before you run the while but this method will cause the browsers become very slow

It is impossible to directly pause a Javascript function within a for loop then later resume at that point.

This is how you should do it

var i = 0; setTimeout(function() < s.innerHTML = s.innerHTML + i.toString(); i++; >,2000); 

The following code is an example of pseudo-multithreading that you can do in JS, it’s roughly an example of how you can delay each iteration of a loop:

var counter = 0; // A single iteration of your loop // log the current value of counter as an example // then wait before doing the next iteration function printCounter() < console.log(counter); counter++; if (counter < 10) setTimeout(printCounter, 1000); >// Start the loop printCounter(); 

While several of the other answers would work, I find the code to be less elegant. The Frame.js library was designed to solve this problem exactly. Using Frame you could do it like this:

var s = document.getElementById("div1"); for (i = 0; i < 10; i++) < Frame(2000, function(callback)< // each iteration would pause by 2 secs s.innerHTML = s.innerHTML + i.toString(); callback(); >); > Frame.start(); 

In this case, it is nearly the same as the examples that use setTimeout, but Frame offers a lot of advantages, especially if the you are trying to do multiple or nested timeouts, or have a larger JS application that the timeouts need to work within.

Источник

Add a delay after executing each iteration with forEach loop

What you want to achieve is totally possible with Array#forEach — although in a different way you might think of it. You can not do a thing like this:

var array = ['some', 'array', 'containing', 'words']; array.forEach(function (el) < console.log(el); wait(1000); // wait 1000 milliseconds >); console.log('Loop finished.'); 
some array // one second later containing // two seconds later words // three seconds later Loop finished. // four seconds later 

There is no synchronous wait or sleep function in JavaScript that blocks all code after it.

The only way to delay something in JavaScript is in a non–blocking way. That means using setTimeout or one of its relatives. We can use the second parameter of the function that we pass to Array#forEach : it contains the index of the current element:

var array = ['some', 'array', 'containing', 'words']; var interval = 1000; // how much time should the delay between two iterations be (in milliseconds)? array.forEach(function (el, index) < setTimeout(function () < console.log(el); >, index * interval); >); console.log('Loop finished.');

Using the index , we can compute when the function should be executed. But now we have a different problem: the console.log(‘Loop finished.’) is executed before the first iteration of the loop. That’s because setTimout is non–blocking.

JavaScript sets the timeouts in the loop, but it doesn’t wait for the timeouts to complete. It just continues executing the code after the forEach .

To handle that, we can use Promise s. Let’s build a promise chain:

var array = ['some', 'array', 'containing', 'words']; var interval = 1000; // how much time should the delay between two iterations be (in milliseconds)? var promise = Promise.resolve(); array.forEach(function (el) < promise = promise.then(function () < console.log(el); return new Promise(function (resolve) < setTimeout(resolve, interval); >); >); >); promise.then(function () < console.log('Loop finished.'); >);

There is an excellent article about Promise s in conjunction with forEach / map / filter here.

I gets trickier if the array can change dynamically. In that case, I don’t think Array#forEach should be used. Try this out instead:

var array = ['some', 'array', 'containing', 'words']; var interval = 2000; // how much time should the delay between two iterations be (in milliseconds)? var loop = function () < return new Promise(function (outerResolve) < var promise = Promise.resolve(); var i = 0; var next = function () < var el = array[i]; // your code here console.log(el); if (++i < array.length) < promise = promise.then(function () < return new Promise(function (resolve) < setTimeout(function () < resolve(); next(); >, interval); >); >); > else < setTimeout(outerResolve, interval); // or just call outerResolve() if you don't want to wait after the last element >>; next(); >); >; loop().then(function () < console.log('Loop finished.'); >); var input = document.querySelector('input'); document.querySelector('button').addEventListener('click', function () < // add the new item to the array array.push(input.value); input.value = ''; >);

Источник

Оцените статью