如何在node.js中创建可中断循环

时间:2014-01-28 16:43:00

标签: node.js events asynchronous

免责声明:我是Node.js的新手,以下说明可能很冗长......

我正在尝试教自己Node.js我正在做的一个小项目。项目构思如下:RaspberryPI运行Node.js应用程序,允许我控制RGB LED条的颜色。该应用程序应该能够设置静态颜色,并运行平滑改变颜色的色轮。

我的想法是创建几个Node.js脚本:

  1. 执行客户端通信,设置静态颜色或能够启动色轮的“控制器”
  2. 每个运行色轮的
  3. “客户端脚本”。其中一个将是“活着”,由“控制器”启动/停止
  4. 我已经能够创建一个支持另一个脚本的小脚本,并且能够使用child.send停止该脚本,如下所示:

    controller.js

    var fork = require('child_process').fork,
        test2 = fork(__dirname + '/test2.js');
    
    setTimeout(function() { test2.send({func: 'quit'}); }, 5000);
    

    这会分叉test2.js脚本,并在5秒后发送一条退出quit的{​​{1}}消息。

    test2.js

    test2.js

    此“客户端脚本”每秒打印一次“Hello”,直到控制器发送function runLoop() { console.log("Hello"); setTimeout(runLoop, 1000); } process.on('message', function(m) { if (m.func === 'quit') { process.exit(0); } }); setTimeout(runLoop, 1000); 消息。

    这很好用 - 5秒后脚本优雅地完成。

    我现在的问题是:如果我实现色轮,我需要一个可能无限循环来改变LED灯条的颜色。上面的(当然还有更短的定时器值 - 我需要10ms这样的东西)是实现可中断循环的可行方法还是有一些我不知道的更整洁的机制呢?

2 个答案:

答案 0 :(得分:2)

如果您使用setTimeout,则甚至不需要分叉新进程。这是我写你的例子的方式:

var ntrvl = setInterval(function() { console.log('Hello'); }, 1000);
setTimeout(function() { clearInterval(ntrvl); }, 5000);

......非常简单。使用setTimeoutsetInterval,您正在使用异步函数,因此您不会阻止事件循环。当计时器启动时,它会运行您的代码,然后等待下一个事件。您应该能够控制所有“客户端”,您将拥有远远超过实际需要的带宽,所有这些都以同样的方式同时进行。

你需要警惕的是你没有阻止剧本。如果您尝试同步执行任何操作(这意味着脚本将在执行下一个命令之前等待操作完成),那么您需要确保它快速运行。如果你必须同步运行处理器/时间密集型任务,那就是你需要分叉一个新进程。

答案 1 :(得分:1)

你让生活变得复杂。您的全球架构如下:

external trigger --> listener ----------> code that changes color
(ie. web client)     (ie. web server)

考虑到这一点,您不需要分叉任何过程,您可以在一个过程中控制LED灯条。在代码中的某处,您将拥有与此类似的对象:

//"led" is the module that allows you to change the color of a led (suppose 4 leds)
var led = require ("led-controller");

var ColorChanger = module.exports = function (){
    this._intervalId = null;
};

ColorChanger.prototype.setColor = function (hex){
    //Color in hexadecimal

    //Cancel any current interval
    cancelInterval (this._intervalId);

    led.color (0, hex);
    led.color (1, hex);
    led.color (2, hex);
    led.color (3, hex);
};

ColorChanger.prototype.wheel = function (hex, ms){
    //Color in hexadecimal
    //"ms" is the time interval between leds going on and off

    //Cancel any current interval
    cancelInterval (this._intervalId);

    //Shutdown all the leds
    led.off (0);
    led.off (1);
    led.off (2);
    led.off (3);

    //Activate the first led
    led.color (0, hex);

    //Current active led
    var curr = 0;

    this._intervalId = setInterval (function (){
        //Each "ms" the current led will go off and the next will go on
        led.off (curr);
        //Next led to activate
        curr = ++curr%4;
        led.color (curr, hex);
    }, ms);
};

然后,侦听器模块使用ColorChanger

var ColorChanger = require ("./color-changer");

var changer = new ColorChanger ();

//Set all the leds to red
changer.setColor ("#FF0000");

//Each 10ms one led goes green and the previous is turned off, in an endless loop
changer.wheel ("#00FF00", 10);