如何在阻塞的nodejs中创建睡眠/延迟?

 罗伯特1980_823 发布于 2023-02-06 09:53

我正在尝试学习nodejs和我正在工作的一个小项目正在编写一个API来控制一些联网的LED灯.

控制LED的微处理器具有处理延迟,我需要将发送到微处理器的命令间隔至少100ms.在C#中,我习惯只调用Thread.Sleep(时间),但我没有在节点中找到类似的功能.

我在节点中使用setTimeout(...)函数找到了几个解决方案,但是,这是异步的并且不会阻塞线程(这是我在这种情况下所需要的).

有人知道阻塞睡眠或延迟功能吗?最好是不仅能旋转CPU,而且精度为+ -10 ms的东西?

6 个回答
  • 使用Node睡眠包.https://www.npmjs.com/package/sleep.

    在您的代码中,您可以使用

    var sleep = require('sleep'); 
    sleep.sleep(n)
    

    睡觉特定的n秒.

    2023-02-06 09:56 回答
  • 最好的解决方案是为您的LED创建单独控制器,它将排队所有命令并以指定的延迟执行它们:

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

    现在你可以打电话Led.exec,它会为你处理所有延误:

    Led.exec(cmd, function() {
      console.log('Command sent');
    });
    

    2023-02-06 09:57 回答
  • 借助ECMA脚本2017(受Node 7.6及更高版本支持),它成为了一种形式:

    function sleep(millis) {
      return new Promise(resolve => setTimeout(resolve, millis));
    }
    
    // Usage in async function
    async function test() {
      await sleep(1000)
      console.log("one second has elapsed")
    }
    
    // Usage in normal function
    function test2() {
      sleep(1000).then(() => {
        console.log("one second has elapsed")
      });
    }
    

    2023-02-06 09:58 回答
  • 只需使用child_process.execSync并调用系统的睡眠功能即可.

    //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]);
    

    我在主应用程序脚本顶部的循环中使用它来使Node等待,直到连接网络驱动器,然后再运行应用程序的其余部分.

    2023-02-06 09:59 回答
  • 我想出的最简单的真正同步解决方案(即没有收益/异步),它可以在所有操作系统上运行而没有任何依赖关系,那就是调用节点进程来评估内联setTimeout表达式:

    const sleep = (ms) => require("child_process")
        .execSync(`"${process.argv[0]}" -e setTimeout(function(){},${ms})`);
    

    2023-02-06 09:59 回答
  • Node本质上是异步的,这就是它的优点,所以你真的不应该阻塞线程,但是因为这似乎是一个控制LED的项目,我会发布一个工作流程,即使它不是一个非常好的,不应该使用(严重).

    while循环将阻塞该线程,因此您可以创建自己的睡眠功能

    function sleep(time, callback) {
        var stop = new Date().getTime();
        while(new Date().getTime() < stop + time) {
            ;
        }
        callback();
    }
    

    用作

    sleep(1000, function() {
       // executes after one second, and blocks the thread
    });
    

    我认为这是阻塞线程的唯一方法(原则上),让它在循环中保持忙碌,因为Node没有内置任何阻塞功能,因为它会排序异步行为的目的.

    2023-02-06 09:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有