Reputation: 1136
Having a list of number [n1,n2...] I want to print the number then sleep for t1, t2 print(n2) sleep for t2 etc.
I manage to "remember" the scope but the problem is that it waits always 1 second only. also when i hardcode a larger value eg 2000 it just prints all the numbers.
With promises:
function sleep(ms) {
return(
new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, ms);
});
);
}
for (let i = 1; i <= 100; i++) {
sleep(i*1000).then(function() {
console.log(i);
});
}
with setTimeout same result
for (let i = 1; i <= 100; i++) {
(function(z) {
setTimeout(
function(){console.log(z);},
z*1000
);
})(i);
}
for (let i = 1; i <= 100; i++) {
(function(z){
setTimeout(
function(){console.log(z);},
z*1000
);
})(i);
}
Upvotes: 2
Views: 75
Reputation: 3454
That is because you start all your Promise
s and setTimeouts()
s simultaniously, their time will run out basically at the same time.
I see two solutions to your problem:
Promise
runs out before continuing your codesetTimeout()
to the next one's delayBoth solutions run asynchronously, which would free up the callstack for other tasks (which is important to do since JavaScript runs single-threaded). The first solution however is more elegant, and keeps your code more readable. That is why I will only go more in-depth into the first one.
For 1. to work, you need to wrap your code (or at least the asynchronous part) in an asynchronous body to be able to use the await
keyword. We will use the await
keyword in combination with a Promise
and setTimeout()
just like you used it, but we will wait for the Promise
to be resolved.
In code, this could look like this:
Note: That wrapped function expression, which is immediately invoked, is called an IIFE.
function sleep(ms) {
return new Promise(res => setTimeout(res, ms));
}
(async function() {
for (let i = 1; i <= 100; i++) {
console.log(i);
await sleep(i*1000);
}
})();
Upvotes: 1