【问题标题】:How to prevent 2 setInterval() function to run at the same time如何防止 2 个 setInterval() 函数同时运行
【发布时间】:2015-07-26 17:16:43
【问题描述】:

我有一个脚本每秒查看一次电话呼叫队列并向用户显示更新。 “现在我的代码将消息写入控制台以进行测试。”

由于我的代码每 1 秒运行一次,因此当用户打开多个表时,同一函数每秒调用 1 x“总标签”。如果我打开了 5 个选项卡,即每秒 5 个请求,这可能会给用户提供虚假信息或导致问题。

有没有办法让我只在活动选项卡上运行setInterval() 函数?我的代码必须在应用程序的每个页面上执行,以确保在有呼入电话或他或她需要注意的事情时通知用户。

这是每秒执行的代码。

<script>
$(function(){

    function isset(a, b){

        if(typeof a !== "undefined" && a){
            return a
        }

        return b;
    }

    setInterval(function() {

        $.getJSON("showMEssages.php", {method: "getMessages"}, function(data){

            if(typeof data.calls === 'undefined' || data.calls.length == 0 || !data.calls){
                console.log('No Messages');
                return;
            }

            $.each(data.calls, function(i, item){

                $.each(item, function(z, c){

                    var interactionId = isset(c.interactionId, 0);
                    var Eic_CallDirection = isset(c.Eic_CallDirection, '');
                    var Eic_State = isset(c.Eic_State, '');
                    var AccoRDI_mid = isset(c.AccoRDI_mid, '');
                    var Eic_RemoteAddress = isset(c.Eic_RemoteAddress, '');

                    if(Eic_State == '' || Eic_CallDirection == ''){
                        return;
                    }

                    //incoming call that is not answered
                    if( Eic_CallDirection == 'I' && Eic_State == 'A'){
                        console.log('Incomming Call From ' + Eic_RemoteAddress + ' MID: ' + AccoRDI_mid );
                        return;
                    }

                    //on hold
                    if( Eic_State == 'H'){
                        console.log('Phone number ' + Eic_RemoteAddress + ' is on hold' );
                        return;
                    }

                    //voicemail
                    if( Eic_State == 'M'){
                        console.log('Phone number ' + Eic_RemoteAddress + ' is on leaving a voicemail' );
                        return;
                    }

                    //connected call
                    if(Eic_State == 'C'){
                        console.log('Live Call With ' + Eic_RemoteAddress );
                        return;
                    }

                    //Dialling call
                    if(Eic_State == 'O'){
                        console.log('Dialling ' + Eic_RemoteAddress );
                        return;
                    }

                    //Dialling call
                    if(Eic_State == 'R'){
                        console.log('Outbound call is rining and waiting for answer ' );
                        return;
                    }

                    //Call Disconnected
                    if(Eic_State == 'I' || Eic_State == 'E' ){
                        console.log('Hungup with ' + Eic_RemoteAddress );
                        return;
                    }

                });
            });
        });

    }, 1000);
});
</script>

有任何替代解决方案吗?

【问题讨论】:

  • here
  • 这可能是一个更好的答案:stackoverflow.com/questions/1060008/…
  • 另外,如果出现问题,通常最好使用setTimeout() 而不是setInterval()。如果它仍应继续运行,只需在回调中重新初始化超时。
  • 从服务器轮询...为什么不使用server-sent eventsweb sockets
  • @Mike 不确定我是否正确理解了您评论中的问题。在上面的代码示例中,您正在从showMEssages.php 轮询,而没有其他参数,例如用户名和密码。服务器发送事件的思想类似于long-polling:客户端(浏览器)向服务器发送请求;连接保持活动状态,服务器仅在有新数据时才响应。除非是跨域请求,否则客户端将发送 cookie。也许打开一个新问题或搜索 SO。

标签: javascript jquery


【解决方案1】:

您可以实现一些机制来同步不同选项卡之间的工作。主要思想是让标签相互通信

例如,一旦用户打开标签,您就会向频道广播一条消息,说“我正在寻找活动的标签”。然后活动选项卡(同频道收听)会响应:“我还活着”,新打开的选项卡不会启动间隔功能。否则它将开始间隔并将自己标记为活动。在实践中,您可能需要做其他事情来消除死锁(例如使用看门狗技术)

还有其他方法可以做到这一点,但总体思路是让选项卡相互通信

一些可能会帮助您实现它的库

https://github.com/tejacques/crosstab

https://github.com/diy/intercom.js/

【讨论】:

  • 谢谢你。如果我理解正确intercom.js 是我需要使用的。方法.once 应该这样做。我应该像这样使用它.once(somethingRandom, myFunctionWithOutIntervalSet , [1])我说的对吗?
  • 嗯,有很多方法可以使用它。是的,您可以使用.once,例如,当用户关注选项卡 A 时,您会广播一条消息,说所有其他选项卡都应该停止间隔。当焦点位于选项卡 B 中时,您重复该过程。这应该可以解决问题
【解决方案2】:

我认为最好在执行setTimeout 回调之前有一个可以检查的标志,您可以使用window.onfocuswindow.onblur 知道选项卡是否具有焦点:

var tabHasFocus = true;
window.onfocus = function() {
   tabHasFocus = true;
}
window.onblur = function() {
   tabHasFocus = false;
}

setInterval(function() {
   if(tabHasFocus) {
      ...
   }
}, 1000);

【讨论】:

    猜你喜欢
    • 2013-01-06
    • 1970-01-01
    • 2021-12-27
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    相关资源
    最近更新 更多