异步回调困难和JavaScript对象比较

异步回调困难和JavaScript对象比较,javascript,node.js,callback,Javascript,Node.js,Callback,我正在学习JavaScript和Node.js,目前我正在制作一个Node.js应用程序来管理我的飞利浦色调灯。我正在努力解决异步和回调问题 首先让我解释一下我想要实现的目标。我有一个函数,它获取所有灯光的“id”,名为getLightsId: function getLightsId(callback){ args ={ path:{"username":"username"} }; client.registerMethod("getLightSta

我正在学习JavaScript和Node.js,目前我正在制作一个Node.js应用程序来管理我的飞利浦色调灯。我正在努力解决异步和回调问题

首先让我解释一下我想要实现的目标。我有一个函数,它获取所有灯光的“id”,名为getLightsId:

function getLightsId(callback){
    args ={
        path:{"username":"username"}
    };

    client.registerMethod("getLightState", "bridge_adress/api/${username}/lights/", "GET");

    client.methods.getLightState(args, function(data,response){
        var id = [];
        for(key in data){
            id.push(key);
        }
        callback(id);
    });
}
然后我有一个函数
getLightState
,它获取由其id确定的特定灯的状态:

function getLightState(id, callback){

    args ={
        path:{"username":"username", "id":id}
    };

    client.registerMethod("getLightState", "http://bridge_address/api/${username}/lights/${id}", "GET");

    client.methods.getLightState(args, function(data,response){
        callback(data);
    });
}
最后,我有一个函数
initLightsState
,它将对象中所有灯光的状态发送给我的客户端。准备好看到丑陋的代码;它很脏,但是,嘿,它很管用

function initLightsState(callback){

    getLightsId(function(idArray) {

        var lightsState = new Object();

        idArray.forEach(function(id) {

            setInterval(function(){getLightState(id, function(state) {

                lightsState[id] = state;
            });},500);
        });

        callback(lightsState);
        io.sockets.on('connection', function (socket) {
            setInterval(function(){
                socket.emit('updateLightsState', lightsState);
            },500);
        });
    });
}
我必须在我的
getLightState
函数中添加一个
setInterval()
,否则它总是向我发送具有相同数据的相同对象。然后,我还使用
setInterval()
my对象向我的客户机发出消息

问题是它显然是在用我的灯光状态向我的客户发送垃圾邮件。这是可行的,但远不是最干净的方法

我想做的是比较服务器端我的灯光的前一个状态和当前状态,并且只有在不同的情况下才将其发送到客户端

但我被电话回访和其他事情缠住了,无法让它工作。有人能告诉我最简单的方法吗


我想我应该使用async和deep equal模块,但我在这里真的迷路了。

我终于找到了一个使用async.瀑布的解决方案

我不确定这是否是最好的方法,但效果相当好: 我终于找到了一个解决方案,我不确定它是否有效,但它是有效的,我使用了async.瀑布,感谢Floby的帮助

 // initialise previousState
 var previousState = "Original";

io.sockets.on('connection', function (socket) {
setInterval(function(){
        async.waterfall([
            function getLightsId(callback) {
                args = {
                    path: {
                        "username": "username"
                    }
                };

                client.registerMethod("getLightState", "http://bridheip/api/${username}/lights/", "GET");

                client.methods.getLightState(args, function (data, response) {
                    var ids = [];
                    for (key in data) {
                        ids.push(key);
                    }
                    callback(null, ids);
                });
            },
            function getLightsState(ids, callback) {
                var lightsState = new Object();
                async.reduce(ids, {}, function(lightsState, id, rcallback) {
                  getLightState(id, function(state) {
                    lightsState[id] = state;
                    rcallback(null, lightsState);
                    });
                }, callback);
            },
    ], 
    function (err, currentState) {
        if(JSON.stringify(currentState) !== JSON.stringify(previousState)){
            io.sockets.emit('updateLightsState', currentState);
            previousState = currentState;
            console.log("state changed");
        }            
    });
},1000);
 });

这是通过数据库完成的吗?或者您正在连接到另一个web服务?我不熟悉这些灯,也不熟悉运行它们的软件。另外,您的框架还有哪些其他部分?只是原始的nodejs吗?没有数据库,lamps附带了一个“桥”,桥命令lamps并提供一个restful api。正如您在我的getLightsId函数中所看到的,我请求其中的api。而且,这只是原始节点,没有其他框架。