How to create a sleep/delay in nodejs that is Blocking?

后端 未结 12 637
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-02 07:00

I\'m currently trying to learn nodejs and a small project I\'m working is writing an API to control some networked LED lights.

The microprocessor controlling the LED

相关标签:
12条回答
  • 2020-12-02 07:30

    Just use child_process.execSync and call the system's sleep function.

    //import child_process module
    const child_process = require("child_process");
    // Sleep for 5 seconds
    child_process.execSync("sleep 5");
    
    // Sleep for 250 microseconds
    child_process.execSync("usleep 250");
    
    // Sleep for a variable number of microseconds
    var numMicroSeconds = 250;
    child_process.execFileSync("usleep", [numMicroSeconds]);
    

    I use this in a loop at the top of my main application script to make Node wait until network drives are attached before running the rest of the application.

    0 讨论(0)
  • 2020-12-02 07:32

    The best solution is to create singleton controller for your LED which will queue all commands and execute them with specified delay:

    function LedController(timeout) {
      this.timeout = timeout || 100;
      this.queue = [];
      this.ready = true;
    }
    
    LedController.prototype.send = function(cmd, callback) {
      sendCmdToLed(cmd);
      if (callback) callback();
      // or simply `sendCmdToLed(cmd, callback)` if sendCmdToLed is async
    };
    
    LedController.prototype.exec = function() {
      this.queue.push(arguments);
      this.process();
    };
    
    LedController.prototype.process = function() {
      if (this.queue.length === 0) return;
      if (!this.ready) return;
      var self = this;
      this.ready = false;
      this.send.apply(this, this.queue.shift());
      setTimeout(function () {
        self.ready = true;
        self.process();
      }, this.timeout);
    };
    
    var Led = new LedController();
    

    Now you can call Led.exec and it'll handle all delays for you:

    Led.exec(cmd, function() {
      console.log('Command sent');
    });
    
    0 讨论(0)
  • 2020-12-02 07:34

    blocking the main thread is not a good style for node because in most cases more then one person is using it. You should use settimeout/setinterval in combination with callbacks.

    0 讨论(0)
  • 2020-12-02 07:42

    It's pretty trivial to implement with native addon, so someone did that: https://github.com/ErikDubbelboer/node-sleep.git

    0 讨论(0)
  • 2020-12-02 07:42

    asynchronous call ping command to block current code to execution in specified milliseconds.

    • ping command is Cross-platform
    • start /b means: start program but not show window.

    code as below:

    const { execSync } = require('child_process')
    // delay(blocking) specified milliseconds
    function sleep(ms) {
        // special Reserved IPv4 Address(RFC 5736): 192.0.0.0
        // refer: https://en.wikipedia.org/wiki/Reserved_IP_addresses
        execSync(`start /b ping 192.0.0.0 -n 1 -w ${ms} > nul`)
    }
    
    // usage
    console.log("delay 2500ms start\t:" + (new Date().getTime() / 1000).toFixed(3))
    sleep(2500)
    console.log("delay 2500ms end\t:" + (new Date().getTime() / 1000).toFixed(3))
    

    notice important: Above is not a precision solution, it just approach the blocking time

    0 讨论(0)
  • 2020-12-02 07:45

    Blocking in Node.js is not necessary, even when developing tight hardware solutions. See temporal.js which does not use setTimeout or setIntervalsetImmediate. Instead, it uses setImmediate or nextTick which give much higher resolution task execution, and you can create a linear list of tasks. But you can do it without blocking the thread.

    0 讨论(0)
提交回复
热议问题