2015-07-11 75 views
1

我在我用來通過LIRC控制空調的Raspberry Pi上構建了我的第一個node.js應用程序。當您想要增加交流單元的溫度時,會調用以下代碼。它每250毫秒發送一次LIRC命令,具體取決於你想增加多少度數。此代碼按預期工作。在Node.js中遞歸setTimeout函數中的錯誤處理

var iDegrees = 5; 
var i = 0; 
var delay = 250 // The delay in milliseconds 

function increaseTemperatureLoop(){ 
    i++;   
    //lirc_node.irsend.send_once("ac", "INCREASE", function() {}); 
    console.log(i); 

    // Call the fucntion/loop again after the delay if we still need to increase the temperature 
    if (i <= iDegrees){ 
     timer = setTimeout(increaseTemperatureLoop, delay); 
    } 
    else { 
     res.json({"message": "Success"}); 
    } 
} 

// Start the timer to call the recursive function for the first time 
var timer = setTimeout(increaseTemperatureLoop, delay); 

我很難與node.js的異步特性一起工作。一旦我的遞歸函數完成,我將json返回到瀏覽器,如上面的代碼所示。按照習慣,我覺得我應該在下面的初始函數調用之後返回一行代碼中的json,但顯然這不會等待所有LIRC調用都成功 - 將它放在函數內部看起來很愚蠢:

var timer = setTimeout(increaseTemperatureLoop, delay); 
res.json({"message": "Success"}); 

如果我有一堆其他的東西我LIRC發送完成後,但我想我的JSON發送回瀏覽器之前做什麼?或者,如果該代碼塊引發錯誤...

我的第二個問題是,我如何正確包裝在try/catch中的LIRC調用,然後如果有錯誤,停止遞歸調用,通過錯誤備份,然後通過這個返回給瀏覽器與實際的錯誤消息一起:

res.json({"message": "Failed"}); 

回答

0
  1. 爲週期執行任務的跟蹤結束時,您可以使用一個回調。
  2. 爲了知道是否完成了所有例行任務,可以使用任務隊列。
  3. 監視並向上報告錯誤 - 可以在 三個相同的回調的幫助下進行。
  4. 一般來說,希望將所有內容都包裝成一個對象。

一些示例進行反思:

var lircTasks = function __self(){ 

    if (typeof __self.tasks === "undefined") __self.tasks = 0; 

    __self.func = { 
     increaseTemperature: function() { 
       // lirc_node.irsend.send_once("ac", "INCREASE_TEMPERATURE", function() {}); 
     }, 
     increaseFanPower: function() { 
       // lirc_node.irsend.send_once("ac", "INCREASE_FANPOWER", function() {}); 
     } 
    } 

    var fab = function() { 

     __self.tasks++; 
     this.i = 0; 
     this.args = arguments[0]; 
     this.callback = arguments[1]; 

     this.run = function __ref(taskName) { 
      if (taskName) this.taskName = taskName; 
      if (this.i<this.args.deg) { 
       try { 
        __self.func[this.taskName](); 
       } catch(e) { 
        __self.tasks--; 
        this.callback({message: "error", error: e, taskName: this.taskName, task: this.args, tasks: __self.tasks}); 
       } 
       this.i++; 
       setTimeout(__ref.bind(this), this.args.delay); 
      } else { 
       __self.tasks--; 
       this.callback({message:"complete", taskName: this.taskName, task: this.args, tasks: __self.tasks}); 
      } 
     } 

    } 

    if ((arguments.length === 2) && (typeof arguments[1] === "function") && arguments[0].deg>0 && arguments[0].delay>=0) { 
     return new fab(arguments[0], arguments[1]); 
    } 

} 

function complete(e) { 
    console.log(e); 
    if (e.tasks === 0) console.log({message: "Success"}); 
} 

lircTasks({deg: 10, delay:100, device: "d1" }, complete).run("increaseTemperature"); 
lircTasks({deg: 20, delay:150, device: "d2" }, complete).run("increaseTemperature"); 
lircTasks({deg: 5, delay:100, device: "d3" }, complete).run("increaseFanPower"); 
+0

謝謝你的職位 - 我能得到這個工作。哪裏是我的JSON響應的最佳位置:res.json({「message」:「Success」}); – user1624184

+0

@ user1624184內部完整函數,而不是'console.log'。 –