在客户端重新连接时,在pubnub history()调用期间等待回调完成

时间:2014-08-26 09:34:45

标签: javascript callback closures pubnub

我的订阅者有两个频道:广播唯一频道。在广播频道,我有所有订阅者收听。 唯一渠道适用于发布商订阅者之间的一对一通信。

我需要实现以下解决方案:如果订阅者脱机/失去连接,在他重新联机后,他需要轮询两个频道以获取每个频道的最新消息并确定如果消息仍然有效,则基于消息对象中的属性:

//HERE IS THE MESSAGE OBJECT THAT THE PUBLISHER SENDS ON THE BROADCAST AND THE UNIQUE
//CHANNELS TO THE SUBSCRIBERS. 
message = {
    alarm: null, //BOOLEAN: DESIGNATES IF THE ALARM IS ON/OFF
    body: null, //STRING: SOME MESSAGE/ALARM TEXT
    image: null, //STRING: SOME IMAGE IF YOU WANT TO APPEAR WITH THE ALARM TEXT
    createdAt: null, //UNIX TIMESTAMP OF WHEN THE MESSAGE WAS CREATED/SENT
    validUntil: null //UNIX TIMESTAMP - AFTER THIS PERIOD THE MESSAGE IS CONSIDERED INACTIVE AND THE SUBSCRIBER SHOULD IGNORE THIS MESSAGE ON RECONNECT
};

以下是订阅者的示例代码(问题在代码中的注释中标记):

$(document).ready(function(){

    var uuid = PUBNUB.uuid(),
        id = 'vlatkorun-' + uuid,        
        controlChannel = 'vlatkorun-control',
        broadcastChannel = 'vlatkorun-broadcast',
        uniqueChannel = 'vlatkorun-unique-';

    var state = {
      id: id,
      uniqueChannel: uniqueChannel
    };

    //INIT PUBNUB
    var pubnub = PUBNUB.init({
        subscribe_key : 'YYY',
        keepalive: 30
    }); 

    //SUBSCRIBE TO THE CONTROL CHANNEL FIRST
    //THE CONTROL CHANNEL IS FOR MAINTENANCE BETWEEN PUBLISHER 
    //AND THE SUBSCRIBERS
    pubnub.subscribe ({
       channel: controlChannel,
       message: function(m){console.log(m)},
       state: state,
       heartbeat: 30,
       connect: function(m){/*console.log(JSON.stringify(m))*/},
       reconnect: function(m){console.log(JSON.stringify(m))}
    }); 

    //NOW SUBSCRIBE TO THE BROADCAST AND THE UNIQUE CHANNELS
    pubnub.subscribe ({
        channel: [broadcastChannel, uniqueChannel],
        state: state,
        message: function(data){
            //SHOW THE ALARM IN THE BROWSER WHEN MESSAGE ARRIVES
            //OUTPUT OMMITED
        },
        connect: function(m){

            //THIS ARRAY IS GOING TO HOLD THE LATEST MESSAGES FROT THE BOTH CHANNELS
            var channelLatestMessages = [];

            //GET THE MOST RECENT MESSAGE ON THE BROACAST CHANNEL
            pubnub.history({
              channel: broadcastChannel,
              count: 1,
              callback: function (m) {
                if(m[0].length > 0)
                {
                    //GO OVER THE RETURNED MESSAGES AND PUT THEM IN THE ARRAY FOR COMPARING LATER
                    $.each(m[0], function(index, value){
                        channelLatestMessages.push(value);
                    });
                }
                //I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK
                console.info(channelLatestMessages);                
              },
            });

            //GET THE MOST RECENT MESSAGE ON THE UNIQUE CHANNEL
            pubnub.history({
              channel: uniqueChannel,
              count: 1,
              callback: function (m) {
                if(m[0].length > 0)
                {
                    //GO OVER THE RETURNED MESSAGES AND PUT THEM IN THE ARRAY FOR COMPARING LATER
                    $.each(m[0], function(index, value){
                        channelLatestMessages.push(value);
                    });
                }

                //I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK
                console.info(channelLatestMessages);
              },
            }); 

            //I HAVE THE VARIABLE POPULATED WITH THE MESSAGES FROM THE CHANNEL IN THE CALLBACK, BUT HERE THE ARRAY IS EMPTY BECAUSE THE CALLBACKS ARENT
            //FISHED. 
            //HERE IS MY QUESTION: HOW CAN I WAIT FOR THE CALLBACKS TO FINISH SO I CAN CONTINUE WITH MY CODE BELLOW???
            console.info(channelLatestMessages);            

            //IF THERE ARE NO MESSAGES DO NOTHING
            if(channelLatestMessages.length == 0) return;   

            //ASSUME THAT THE FIRST MESSAGE IN THE ARRAY IS THE MOST RECENT
            latestMessage = channelLatestMessages[0];

            //NOW FIGURE OUT THE MOST RECENT MESSAGE
            $.each(channelLatestMessages, function(index, message){
                if(latestMessage.createdAt < message.createdAt)
                {
                    latestMessage = message;                    
                }
            });         

            //GET THE CURRENT DATE IN UNIX TIMESTAMP
            var currentDate = parseInt(moment().format('X'));
            //CHECK IF THE MESSAGE VALIDITY IS EXPIRED
            if(currentDate > latestMessage.validUntil) return;          

            //HERE WE CAN SHOW THE LATEST MESSAGE IN THE BROWSER
            //OUTPUT OMMITED
        },
        reconnect: function(m){//THE SAME LOGIN LIKE IN THE CONNECT METHOD APPLIES HERE}
    });         
});

如何等待回调完成,以便 channelLatestMessages 充满来自广播唯一频道的最新消息,以便我可以进一步确定哪条消息更新,以及更新的消息是否仍处于活动状态?

1 个答案:

答案 0 :(得分:0)

你的逻辑可以像这样运行:

historyCall-1的回调调用historyCall-2。 historyCall-2的回叫电话&#34;消息年龄检测&#34;逻辑。

通过这种方式,我们可以同步实现异步行为,并且是唯一的方式&#34;消息年龄检测&#34;逻辑运行是指我们知道历史调用1和2已完成的事实。

geremy