简体   繁体   中英

Sleep in Node.js

Assumed that there is no "native" way to achieve this, my solution-like was

sleep = function(time) {
        var stop = new Date().getTime();
        while(new Date().getTime() < stop + time) {
            ;
        }
        return new Promise((r,_)=> r())
      }

So doing sleep(1000*3).then(()=>console.log("awake")) it will sleep 3 seconds and then resolve the Promise :

(be aware that it will freeze this page one sec.)

 sleep = function(time) { var stop = new Date().getTime(); while (new Date().getTime() < stop + time) {; } return new Promise((r, _) => r()) } console.log("sleeping...") sleep(1000 * 1).then(() => console.log("awake"))

Assumed that this will run in the main thread it will freeze the main process so that doing

sleep(1000*1).then(()=>console.log("awake")); console.log("Hello")

it will result in a output

VM2628:1 Hello
VM2628:1 awake

at very end of the sleep. Of course doing

setTimeout(()=>sleep(1000*3).then(()=>console.log("awake")),1000);console.log("Hello")
VM2815:1 Hello
undefined
VM2815:1 awake

will make it async, but it does not address my need (to put to sleep my main process). Any better way?

[UPDATE] Promisified version

/**
 * Sleep for time [msec]
 * @param time int milliseconds
 * @return Promise delayed resolve
 * @usage
    sleep(1000*3).then(()=>console.log("awake"))
 */
sleepP: function (time) {
  return new Promise((resolve, reject) => {
    var stop = new Date().getTime();
    while (new Date().getTime() < stop + time) {
      ;
    }
    return resolve(true)
  });
}

that can be called like

await sleepP( 1000 * 3 );

There is no need to freeze at all. Because of javascripts asynchronicity we can leave a part of the code for some time and resume later. At first we need a promising timer:

 const timer = ms => new Promise( res => setTimeout(res, ms));

Then we can simply use it:

console.log("wait 3 seconds")
timer(3000).then(_=>console.log("done"));

Or with a bit syntactic sugar:

(async function(){
  console.log("wait 3 seconds");
  await timer(3000);
  console.log("done");
})()

If you really want to freeze ( very bad ), you don't need promises at all:

function freeze(time) {
    const stop = new Date().getTime() + time;
    while(new Date().getTime() < stop);       
}

console.log("freeze 3s");
freeze(3000);
console.log("done");
function sleep(time, func){
    if (typeof func === 'function'){
        const timer = ms => new Promise( res => setTimeout(res, ms));
        timer(time).then(i=>func());
    }
    else{
        console.log('What about the function bro?')
    }
}
sleep(1000, function(){
    console.log('hello')
    console.log('test')
    var arr = [1,2,3,4]
    arr.forEach(i => console.log(i))
})

Since Node v15.0.0 there's a new way to sleep by using the Timers Promises API .

import {setTimeout} from 'timers/promises';

const bucket = ['a', 'b', 'c'];

for(const item of bucket) {
    await getItem(item);
    await setTimeout(100);
}

If you want to use also use the regular setTimeout timer you can alias the promise timer.

import {setTimeout as sleep} from 'timers/promises';

I have an issue where I'm uploading to a remote database using an asynchronous write and it goes too fast, and I hit a rate limiter.

So I need to actually pause between sections of code.

My application isn't in a browser or a server, it's just a command line utility so I'm not concerned about blocking the main execution thread.

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