danday74
danday74

Reputation: 57185

Sleep main thread but do not block callbacks

This code works because system-sleep blocks execution of the main thread but does not block callbacks. However, I am concerned that system-sleep is not 100% portable because it relies on the deasync npm module which relies on C++.

Are there any alternatives to system-sleep?

var sleep = require('system-sleep')
var done = false

setTimeout(function() {
  done = true
}, 1000)

while (!done) {
  sleep(100) // without this line the while loop causes problems because it is a spin wait
  console.log('sleeping')
}

console.log('If this is displayed then it works!')

PS Ideally, I want a solution that works on Node 4+ but anything is better than nothing.

PPS I know that sleeping is not best practice but I don't care. I'm tired of arguments against sleeping.

Upvotes: 0

Views: 1251

Answers (2)

jfriend00
jfriend00

Reputation: 707836

Collecting my comments into an answer per your request:

Well, deasync (which sleep() depends on) uses quite a hack. It is a native code node.js add-on that manually runs the event loop from C++ code in order to do what it is doing. Only someone who really knows the internals of node.js (now and in the future) could imagine what the issues are with doing that. What you are asking for is not possible in regular Javascript code without hacking the node.js native code because it's simply counter to the way Javascript was designed to run in node.js.

Understood and thanks. I am trying to write a more reliable deasync (which fails on some platforms) module that doesn't use a hack. Obviously this approach I've given is not the answer. I want it to support Node 4. I'm thinking of using yield / async combined with babel now but I'm not sure that's what I'm after either. I need something that will wait until the callback is callback is resolved and then return the value from the async callback.

All Babel does with async/await is write regular promise.then() code for you. async/await are syntax conveniences. They don't really do anything that you can't write yourself using promises, .then(), .catch() and in some cases Promise.all(). So, yes, if you want to write async/await style code for node 4, then you can use Babel to transpile your code to something that will run on node 4. You can look at the transpiled Babel code when using async/await and you will just find regular promise.then() code.

There is no deasync solution that isn't a hack of the engine because the engine was not designed to do what deasync does.

Javascript in node.js was designed to run one Javascript event at a time and that code runs until it returns control back to the system where the system will then pull the next event from the event queue and run its callback. Your Javascript is single threaded with no pre-emptive interruptions by design. Without some sort of hack of the JS engine, you can't suspend or sleep one piece of Javascript and then run other events. It simply wasn't designed to do that.

Upvotes: 1

C.Unbay
C.Unbay

Reputation: 2826

var one = 0;

function delay(){
 return new Promise((resolve, reject) => {
   setTimeout(function(){
     resolve('resolved')
   }, 2000);
 })
}


while (one == 0) {
  one = 1;
  async function f1(){
    var x = await delay();
    if(x == 'resolved'){
      x = '';
      one = 0;
      console.log('resolved');
      //all other handlers go here... 
      //all of the program that you want to be affected by sleep()
      f1();
    }
  }
  f1();
}

Upvotes: 1

Related Questions