简体   繁体   中英

sleep functionality in browser/node js

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);
}

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:

  1. You could wait until a Promise runs out before continuing your code
  2. You could add the delay of the previous setTimeout() to the next one's delay

Both 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); } })();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM