簡體   English   中英

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

[英]How to make clearTimeout work properly to cancel(break) setTimeout loop?

我正在使用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);

    }

確保在開始和停止時清除clearTimeout,也不需要檢查是否設置了超時。 此外,由於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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM