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

时间:2014-04-02 18:50:09

标签: javascript node.js callback

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

首先让我解释一下我想要实现的目标。我有一个功能,可以获得" id"在我的所有灯光中,named 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);
        });
    });
}

我必须将setInterval()放到我的getLightState函数中,否则它总是向我发送具有相同数据的相同对象。然后我也向我的客户发出setInterval()我的对象。

问题在于它显然是在向我的客户发送垃圾邮件状态。它有效,但它远非最简洁的方法。

我想要做的是将服务器端以前的状态与当前的状态进行比较,并且只有在不同的情况下将其发送给客户端

但是我仍然坚持使用回调和一切,并且无法让它发挥作用。有人可以告诉我最简单的方法吗?

我认为我应该使用异步和深度相等的模块,但我真的迷失了......

1 个答案:

答案 0 :(得分:0)

我终于使用https://github.com/caolan/async

中的async.waterfall找到了解决方案

我不确定这是否是最好的方法,但效果很好: 我终于找到了解决方案,我不确定它是否有效,但它有效,我使用了async.waterfall,感谢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);
 });