如何使clearTimeout正常工作以取消(中断)setTimeout循环?

时间:2019-03-26 06:04:37

标签: javascript node.js raspberry-pi settimeout cleartimeout

我正在使用Node.js构建可读取USB LoRa模块数据并控制Raspberry Pi GPIO引脚的应用程序。

主要有三个功能:

  1. 设置GPIO开启(给定引脚0信号)

  2. 关闭GPIO(给定引脚1信号)

  3. 将GPIO设置为在一段时间后关闭(使用setTimeout函数)

主要功能运行良好。

问题是在setTimeout循环中,我想随时终止它。

我尝试使用clearTimeout来取消setTimeout循环,但似乎不起作用。我在做错什么吗?

例如。

在LoRa收到的数据包中使用字符串“ TurnOn15s”。 我无法随时终止超时。我必须等到15秒结束才能关闭GPIO引脚。如果我在超时执行期间调用deviceTurnOff(1)函数,则在循环结束后将获得两个输出。

程序输出如下:

// Output by `deviceTurnOn(0,15000)` from received LoRa packet.
Received:0, the solenoid valve has been opened!                                 
Received packet: !20!96 0 0 0 53 0 0 28 11 3 TurnOn15s RSSI: -40 SNR:   6

// Output by `setTimeout` function.
Received:1, the solenoid valve has been closed!                                 

// Output by deviceTurnOff(1) from received LoRa packet.
Received:1, the solenoid valve has been closed!                                 
Received packet: !18!96 0 0 0 53 0 0 29 9 3 TurnOff RSSI: -41 SNR:   7 

这是部分代码:

var turnOffTimeout = null; // turnOffTimeout

// Control Raspberry Pi GPIO pins.
function deviceTurnOn(controlValueType, timeout) {

  // Do Turn On Raspberry Pi GPIO pins.
  if (timeout == -1) {

    // if no time string in the packet.
    console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
    OutputDevice.writeSync(controlValueType);
  } else {

    // if contains time string in the packet.
    console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
    OutputDevice.writeSync(controlValueType);
    turnOffTimer(timeout);
  }
}

// Control Raspberry Pi GPIO pins.
function deviceTurnOff(controlValueType) {

  // Do Turn Off Raspberry Pi GPIO pins.
  console.log(`Received:${controlValueType}, the solenoid valve has been closed!`);
  OutputDevice.writeSync(controlValueType);
  // clearTimeout
  if (turnOffTimeout) {
    clearTimeout(turnOffTimeout);
  }
}


// Raspberry Pi GPIO pins turn off timeout.
function turnOffTimer(timeout) {
  turnOffTimeout = setTimeout(function() {
    deviceTurnOff(1);
  }, timeout);
}

包含三个功能: deviceTurnOndeviceTurnOffturnOffTimer

函数调用的格式为

deviceTurnOff(1);
deviceTurnOn(0,timeout);

// Timeout is milliseconds

更新;

我尝试如下修改程序,得到与先前版本代码相同的输出,但问题仍未解决。

 var turnOffTimeout = null; // turnOffTimeout

    // Control Raspberry Pi GPIO pins.
    function deviceTurnOn(controlValueType, timeout) {
        // Do Turn On Raspberry Pi GPIO pins.

        if (timeout == -1) {

            // if no time string in the packet.
            console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
            OutputDevice.writeSync(controlValueType);
        }
        else {

            // if contains time string in the packet.
            console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
            OutputDevice.writeSync(controlValueType);
            // clearTimeout.
            clearTimeout(turnOffTimeout);
            // set new timeout.
            turnOffTimeout = setTimeout(function () {
                deviceTurnOff(1);
            }, timeout);
        }
    }

    // Control Raspberry Pi GPIO pins.
    function deviceTurnOff(controlValueType) {

        // Do Turn Off Raspberry Pi GPIO pins.
        console.log(`Received:${controlValueType}, the solenoid valve has been closed!`);
        clearTimeout(turnOffTimeout);
        OutputDevice.writeSync(controlValueType);

    }

1 个答案:

答案 0 :(得分:2)

确保在启动和停止时都清除了timeout,也不需要检查是否设置了超时。另外,实际上确实不需要第三种功能来取消计时器,因为clearTimeout已经存在:

var timeout;
var timeout_ms = 10000;

var stop = function(){
 clearTimeout(timeout);
 turnOff();
}

var start(){
 clearTimeout(timeout); // clear existing t/o just in case
 timeout = setTimeout(turnOff,timeout_ms);
 turnOn();
}