0

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
danday74
  • 52,471
  • 49
  • 232
  • 283
  • So, you're tired of arguments about how to properly use the "single threaded" node.js. You need to go find another programming environment that lets you run multiple threads. Then, you can sleep to your heart's content. If you're going to stay with node.js, I really suggest you learn how to program in it. There is no sleep in node.js. If you use a library that sleeps the main thread, then the event queue is blocked and nothing else can happen. That's how it works. async/await doesn't sleep either. It is just syntactical help for `.then()` callbacks. – jfriend00 Sep 10 '17 at 05:48
  • 1
    Oh, to summarize, only the main thread runs callbacks/events so if you block the main thread (node.js runs Javascript only in the main thread), callbacks from the event queue are blocked too. You cannot change that. So, what your title asks for is simply not something you can do in node.js. – jfriend00 Sep 10 '17 at 05:52
  • 1
    @jfriend00 if its not possible in node then why does the code I gave in the question work? Please read it properly. I know how to use promises and callbacks. For my own reasons I don't wish to use them here. Also I'm using Node 4 so async/await is not available to me. – danday74 Sep 10 '17 at 08:21
  • 1
    Further research reveals that deasync is a fork of another project. The other project warns not to use it as it is just a hack. Since system-sleep relies on deasync I wouldn't use that either. – danday74 Sep 10 '17 at 10:17
  • 1
    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. That's what I'm trying to communicate to you. – jfriend00 Sep 10 '17 at 15:29
  • If you explained to us what your actual problem is that is driving this need, then we might be able to offer a different/better solution to the actual problem. – jfriend00 Sep 10 '17 at 15:30
  • 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. – danday74 Sep 11 '17 at 07:00
  • 1
    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, again, I'm not really understanding what you're trying to accomplish. 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. There is no deasync solution that isn't a hack of the engine because the engine was not designed to do what deasync does. – jfriend00 Sep 11 '17 at 07:11
  • ok thanks jfriend your time is appreciated. If you want to put an answer to the effect of your comments I'll be happy to accept. – danday74 Sep 11 '17 at 07:13

2 Answers2

1
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();
}
Ahmed Can Unbay
  • 2,694
  • 2
  • 16
  • 33
  • thanks for the response. Is async available on Node 4? Is it es7? Either way I appreciate the reply but am ideally looking for something that runs on Node 4. +1 – danday74 Sep 10 '17 at 02:47
  • No problem, I don't know, I don't think so. Give it a try. If it does not work try to run your app with `node --harmony-async-await app.js` @danday74 – Ahmed Can Unbay Sep 10 '17 at 02:51
1

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.

jfriend00
  • 683,504
  • 96
  • 985
  • 979