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.
Related
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);
I wrote a code, it does not stop the function, but is there such kind of way to do it? Or maybe there is a better way...
let stopper = false;
const toBeLowPriority = () => {
for(let i = 0; i < Math.pow(10, 9); i += 1) {
if(stopper) {
console.log("for loop stopped");
return
}
// do some stuff
let k = Math.random();
if (k === 0.5) {
console.log(k);
}
}
console.log("for loop done fully");
}
setTimeout(
() => {
stopper = true;
}, 500
);
toBeLowPriority();
As your method toBeLowPriority must end before going into the setTimeout, that will never happen.
You can change the function to run only for several times then continue on a setImmediate. (or timeout)
let stopper = false;
const toBeLowPriority = (start=0, end = Math.pow(10, 9), checkEvery = 1000) => {
for(let i = start; i < end; i++) {
if(stopper) {
console.log("for loop stopped at", i);
return
}
// do some stuff
let k = Math.random();
if (k === 0.5) {
console.log(k);
}
if( i >= checkEvery) {
return setImmediate( () => toBeLowPriority(i, end, checkEvery) );
}
}
console.log("for loop done fully");
}
toBeLowPriority();
setTimeout(
() => {
stopper = true;
}, 500
);
And yes, now toBeLowPriority is no more synchrone.
Function that can be stopped must have been designed for such case. But as nearly everything in current JS is asynchronous, you will probably never get a such case in real life.
function randomNum(){
let data;
for(let i=1;i<=10;i++){
let time = Math.random()*100;
setTimeout(()=>console.log(i,time),time)
}
}
randomNum();
For Each iteration, the program needs to stop for random time, then i should be printed and the loop continued
function randomNum() {
let timeToWait = 0; // here
for (let i = 1; i <= 10; i++) {
let time = Math.random() * 100;
timeToWait += time; // here
setTimeout(() => {
console.log(i, time);
}, timeToWait); // update here. Updated
}
}
randomNum();
async function randomNum2() {
for (let i = 1; i <= 10; i++) {
let time = Math.random() * 100;
await new Promise((resolve) => {
setTimeout(() => {
console.log(i, time);
resolve();
}, time);
})
}
}
randomNum2();
You have to calculate time to wait for the next time.
In this case, in "next" time of the loop, time need to wait is total time to wait of before times.
Update the way using async/await.
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.
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();