recursion - Error Handling in a Recursive setTimeout Function in Node.js -
i'm building first node.js application on raspberry pi using control air conditioner via lirc. following code called when want increase temperature of ac unit. sends lirc command every 250 milliseconds depending on how many degrees want increase by. code works expected.
var idegrees = 5; var = 0; var delay = 250 // delay in milliseconds function increasetemperatureloop(){ i++; //lirc_node.irsend.send_once("ac", "increase", function() {}); console.log(i); // call fucntion/loop again after delay if still need increase temperature if (i <= idegrees){ timer = settimeout(increasetemperatureloop, delay); } else { res.json({"message": "success"}); } } // start timer call recursive function first time var timer = settimeout(increasetemperatureloop, delay);
i'm having hard time working asynchronous nature of node.js. once recursive function done, return json browser shown in code above. habit, feel should return json in line of code after initial function call below wouldn't wait of lirc calls successful - seems silly have inside of function:
var timer = settimeout(increasetemperatureloop, delay); res.json({"message": "success"});
what if have bunch of other stuff after lirc sends done before want send json browser? or if block of code throws error...
my second question is, how wrap lirc call in try/catch , if there error, stop recursive calls, pass error up, , pass browser along actual error message:
res.json({"message": "failed"});
- for track end of cycle execution task, can use callback.
- in order know whether completed routine tasks, can use task queue.
- monitor , report bugs top - possible of 3 of same callback.
- in general, desirable wrap single object.
some example reflection:
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");
Comments
Post a Comment