【问题标题】:Error Handling in a Recursive setTimeout Function in Node.jsNode.js 中递归 setTimeout 函数中的错误处理
【发布时间】:2015-07-11 06:05:25
【问题描述】:

我正在我的 Raspberry Pi 上构建我的第一个 node.js 应用程序,我用它来通过 LIRC 控制空调。当您想提高交流单元的温度时,将调用以下代码。它每 250 毫秒发送一个 LIRC 命令,具体取决于您希望将其增加多少度。此代码按预期工作。

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 发送回浏览器之前,我还有很多其他事情要做,该怎么办?或者如果该代码块抛出错误怎么办......

我的第二个问题是,我如何正确地将 LIRC 调用包装在 try/catch 中,然后如果出现错误,停止递归调用,将错误传递回去,然后将其传递回浏览器实际的错误信息:

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

【问题讨论】:

    标签: node.js recursion raspberry-pi settimeout


    【解决方案1】:
    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");
    

    【讨论】:

    • 感谢您的帖子 - 我能够完成这项工作。放置我的 json 响应的最佳位置在哪里: res.json({"message": "Success"});
    • @user1624184 内部完成函数而不是console.log
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多