【问题标题】:jquery ajax remove previous requestsjquery ajax 删除以前的请求
【发布时间】:2016-06-25 03:35:21
【问题描述】:

场景: 我有一个消息页面,其中包含一个容器,其左侧部分包含要发送消息的联系人和组,右侧有对话流。对话流通过 ajax 加载,另一方面单击任何联系人或组。this is what it looks like 将使用包含 setinterval 函数的 javascript 文件加载右侧的内容,该函数每 5 秒执行一次以检查数据库中的新消息并抓取该消息以将其显示在对话 div 中。

问题: 在第一次加载页面时,当我单击联系人或组时,显然内容已加载并且 setinterval 函数会立即运行。当我单击另一个联系人或组时,再次加载内容并再次执行 setinterval 函数,问题是当您尝试查看 chrome 开发人员工具时,现在有两个 setinterval 函数正在运行。 As you can see in this image, there are two requests now, 1 for contact and 1 for group since i clicked a contact and a group。在点击更多联系人和群组时,请求会不断增加。

这是点击联系人或群组时通过 ajax 加载内容的代码:

$('.my_contacts a.list-group-item,.my_groups a.list-group-item,.new_message .list-group-item a').click(function(){
        var href=$(this).attr('href');
        $('.list-group-item').removeClass('active');
        $(this).addClass('active');
        $.ajax({
            url:href,type:'post'
        }).done(function(d){
            $('#center-wing').html(d);
        });
        return false;
    });

这是加载的ajax数据里面的内容:

...more html content here
<script>
$(function(){
    $.getScript("res/js/custom/in-page/message.js");
});
</script>

这是 message.js 中每 5 秒运行一次的代码:

if(notification == true){
        checkNewMsgId=setInterval(function(){
            $.ajax({
                url:'message/check_new_message/' + recipient + '/' + type,
                type:'post'
            }).done(function(d){
                if(d.length > 0){
                    var obj={};
                    lastmsg.addClass('hide');
                    reset_inactivity();
                    for(var o in d){
                        var date=new Date(d[o].SentDate),time=format_time(date);

                        bubble_tpl_left.find('.bubble').attr('data-pk',d[o].Remarks);

                        if(d[o].SenderId == recipient){
                            lastmessagedate=format_date(date);
                            lastmessagetime=time;
                        }

                        if(type == 'CustomGroup') bubble_tpl_left.find('.msg_sender').removeClass('hide').html(d[o].FirstName + " " + d[o].LastName);

                        send(d[o].Reply,time,bubble_tpl_left);

                        obj.title=name;
                        obj.body=d[o].Reply;
                    }
                    if(pagehidden == true){
                        ding.play();push_notify(obj);
                    }else blop.play();
                }
            });
        },5000);
    }

...对不起,长篇大论。我真的坚持这一点,我尝试在执行 setinterval 之前清除间隔。

帮助将不胜感激 :)

【问题讨论】:

  • 如果您希望它只运行一次,请使用 setTimeout()

标签: jquery ajax


【解决方案1】:

(1) 有两个功能。一个为群组加载对话 (loadConversion()),另一个为对话更新消息 (updateMessages())。

(2) 当用户点击组时调用loadConversion()。当该 ajax 调用返回时,它应该在等待 5 秒后调用setTimeout()(而不是setInterval())来执行updateMessages()。当updateMessages()中的ajax调用返回时,等待5秒后会再次调用setTimeout()调用updateMessages()。这设置了持续更新。

(3) 但是当用户点击一个组时,你需要在调用loadConversion() 之前取消任何现有的计时器并中止任何未完成的ajax 调用。 (或者您可以在进行下一次 ajax 调用之前在 loadConversion() 中执行此操作。)


setTimeout() 函数返回一个 timerId。将其存储在变量中。然后您可以将其传递给clearTimout() 以取消计时器。

同样,$.ajax() 函数返回一个 jqXHR 对象,可用于中止 ajax 调用。

【讨论】:

    【解决方案2】:

    将整个页面视为一个页面,将每个单独的区域视为页面的一部分,而不是一个新文档。

    不要将您的 javascript 与您正在为右侧部分加载的页面一起加载。 javascript 应该是主文档的一部分,而不是该部分的一部分。您将获得多个间隔,因为每次重新加载页面的该部分时,您都在运行该 js 并启动一个新的 setInterval - 它会继续运行。

    使用隐藏的输入字段来存储当前选定联系人的href,并让您的重复 AJAX 代码块将该 href 发送到从数据库请求/返回新消息的 PHP 文件。

    /* javascript/jQuery: */
    
    $('.my_contacts a.list-group-item,.my_groups a.list-group-item,.new_message .list-group-item a').click(function(){
        var href=$(this).attr('href');
        $('#curr_href').val(href); //store current href
        $('.list-group-item').removeClass('active');
        $(this).addClass('active');
        $.ajax({
            type: 'post',
             url: href
        }).done(function(d){
            $('#center-wing').html(d);
        });
        return false;
    });
    <!-- HTML: -->
    
        <!-- stick it down at bottom of body, like so -->
        <input type="hidden" id="curr_href" />
      </body>
    </html>

    您的重复 AJAX(应该是主文档的一部分,而不是与聊天记录一起加载)可以执行以下操作:

    var href = $('#curr_href').val();
    $.ajax({
        type:'post',
         url: href
    }).done(function(d){
      //etc etc etc

    在这个用例中,您还应该仔细研究使用递归 setTimeout 而不是 setInterval:

    http://www.erichynds.com/blog/a-recursive-settimeout-pattern

    setTimeout or setInterval?

    【讨论】:

    • 我还没有应用您的解决方案,但我将脚本标签从加载的部分转移到了主文档。所以现在的代码就像这样:$.ajax({ url:href,type:'post' }).done(function(d){ $('#center-wing').html(d); $.getScript("res/js/custom/in-page/message.js"); }); return false;
    • 仍然不起作用。多个请求仍在后台运行。似乎保留了ajax回调中加载的脚本。有没有办法以某种方式删除在后台运行的脚本?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    相关资源
    最近更新 更多