【问题标题】:How to prevent setInterval function from executing twice in Javascript?如何防止 setInterval 函数在 Javascript 中执行两次?
【发布时间】:2018-05-11 06:35:37
【问题描述】:

我正在拨打JS Ajax 电话以每2 秒更新一次页面的内容。为此,我使用setInterval 方法。我注意到我的setInterval 方法执行了两次,结果我得到了重复的输出。检查图片以供参考。

我的 Flask 后端 - routes.py

@app.route('/image/<im>')
@login_required
def image(im):
    image_src=[im+'/'+i for i in  os.listdir(os.path.join(app.static_folder,im))]
    rows=math.ceil(len(image_src)/3)
    print(image_src)
    return render_template('dashboard.html',title='Welcome',images=image_src,rows=rows,image_date=im)

我的 HTML - dashboard.html

{% extends "base.html" %}
{% block content %}

<div class="image-area">


<div class="container dash-container main-body" >
    <hr>
    <div class="row">
        <br>
        <hr >
        <br>
        <div class="col-md-12">
            <div class="jumbotron ">
                <h1 id="hdr">DASHBOARD</h1>
            </div>
        </div> 
    </div>

{% if images %}

<div class="row" id="info">

    <a href="{{ url_for('dashboard') }}"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></a>
</div>
<br><br>
<div class="row">
        <div class="col-md-12" id="info">
            {% set ns = namespace(counter=0) %}
            <table class="table table-hover table-condensed table-bordered images-table" cellspacing="5" cellpadding="5">
                {% for row in range(rows) %}
                <tr class="image-hover">
                    {% for data in range(3) %}
                        {% if ns.counter  < images|length %}
                            <td style="width:10%;">
                                <a href="{{ url_for('display',file=images[ns.counter][10:],folder=images[ns.counter][0:10]) }}"><img src="{{ url_for('static',filename=images[ns.counter]) }}" alt="User Image" width="200" height="180"></a>
                                <br>
                                {% set ns.counter = ns.counter + 1 %}
                            </td>
                        {% endif %}
                    {% endfor %}
                </tr>
                {% endfor %}
            </table>
        </div>
    </div>

{% endif %}

</div>
</div>

<script type="text/javascript">

    var first_time = 0;
    var current_count = 0;
    var total_count = 0;

    function update(){
            if (window.first_time == 0){
                window.current_count = $('td').length;
                window.total_count = window.current_count;
                window.first_time = 1;
                //var txt = $("<p class='notify'></p>").text("No new images");
                $('body').append("<p class='notify'>No new images</p>");

            }
            else {

                window.total_count = $('td').length;
                if (window.total_count>window.current_count){
                    $('.notify').text(window.total_count-window.current_count + " images added !");
                    $('html, body').animate({scrollTop:$(document).height()}, 'slow');
                    //window.alert(total_count-current_count + ' images added !');
                    window.current_count = window.total_count;

                }
            }

    }
    setInterval(function(){ $('.image-area').load("{{ url_for('image',im=image_date) }}"); update(); }, 2000);
</script>

{% endblock %}

base.HTML-

<!DOCTYPE html>
<html>
<head>
    {{ moment.include_jquery() }}
    {{ moment.include_moment() }}
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/base.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/about.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/index.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/dashboard.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/display.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/feedback.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles/login.css') }}">

    <link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">
    {% if title %}
    <title>{{ title }}</title>
    {% else %}
    <title>Welcome_segregator</title>
    {% endif %}
</head>
<body>



    <nav class="navbar navbar-fixed-top  navbar-custom">
    <div class="container" >
    <div class="navbar-header">

            {% if current_user.username %}
            <a class="navbar-brand nav-custom" href="{{ url_for('index') }}" ><span id="header"><span id="logo"><strong>Welcome </strong></span id="header"><strong>{{ current_user.username|striptags }} !</strong></span></a>
            {% else %}
            <a class="navbar-brand nav-custom" href="{{ url_for('index') }}"><span id="header"><span id="logo"><strong>Welcome </strong></span></span></a>
            {% endif %}
    </div>
    <ul class="nav navbar-nav navbar-right " >
            <li class="nav-custom"><a class="nav navbar-nav" href="{{ url_for('index') }}"><span class="glyphicon glyphicon-home "> <span id="header"><strong>Home</strong></span></a></li>
            <li><a class="nav navbar-nav" href="{{ url_for('dashboard') }}"><span class="glyphicon glyphicon-dashboard"> <span id="header"><strong>Dashboard</strong></span></a></li>
            <li><a class="nav navbar-nav" href="{{ url_for('about') }}"><span class="glyphicon glyphicon-user"> <span id="header"><strong>About Us</strong></span></a></li>
            <li><a class="nav navbar-nav" href="{{ url_for('feedback') }}"><span class="glyphicon glyphicon-pencil"> <span id="header"><strong>Feedback</strong></span></a></li>
            {% if current_user.is_anonymous %}
            <li><a class="nav navbar-nav" href="{{ url_for('login') }}"><span class="glyphicon glyphicon-log-in"> <span id="header"><strong>Login</strong></span></a></li>
            {% else %}
            <li><a class="nav navbar-nav" href="{{ url_for('logout') }}"><span class="glyphicon glyphicon-off"> <span id="header"><strong>Logout</strong></span></a></li>
            {% endif %}

    </ul>
      </div>
    </nav>


        {% with messages = get_flashed_messages() %}
        {% if messages %}
        <ul>
            {% for message in messages %}
            <li>{{ message }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}


</body>
</html>

setInterval 方法每 2 秒更新一次页面,然后调用 update() 函数。 update 函数在 HTML 文件的末尾实现了一个自定义通知,如果有任何新项目,它会通知用户。正如您在图 1 和图 2 中看到的,通知在页面上发送了两次。

重要:- 不会立即添加重复值。对于没有新图像的情况,在 2 秒后添加消息“没有新图像”,即显示重复的“无新图像”之间有 2 秒的间隙。但是,当有一个新图像时,副本不会在 2 秒后到达,而是同时添加。即消息“添加了 5 张图像”及其重复版本同时到达屏幕。

请注意底部更新的重复消息。

注意底部的重复项。这里有 5 个新图像添加到仪表板,因此通知是 5,这是正确的,但显示是重复的。

我希望通知只显示一次。 请帮忙。


编辑 1: - 这是完整呈现的 HTML

<!DOCTYPE html>
<html>
<head>
    <script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
<script>
moment.locale("en");
function flask_moment_render(elem) {
    $(elem).text(eval('moment("' + $(elem).data('timestamp') + '").' + $(elem).data('format') + ';'));
    $(elem).removeClass('flask-moment').show();
}
function flask_moment_render_all() {
    $('.flask-moment').each(function() {
        flask_moment_render(this);
        if ($(this).data('refresh')) {
            (function(elem, interval) { setInterval(function() { flask_moment_render(elem) }, interval); })(this, $(this).data('refresh'));
        }
    })
}
$(document).ready(function() {
    flask_moment_render_all();
});
</script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="/static/styles/base.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/about.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/index.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/dashboard.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/display.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/feedback.css">
    <link rel="stylesheet" type="text/css" href="/static/styles/login.css">

    <link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">

    <title>Welcome</title>

</head>
<body>



    <nav class="navbar navbar-fixed-top  navbar-custom">
    <div class="container" >
    <div class="navbar-header">


            <a class="navbar-brand nav-custom" href="/index" ><span id="header"><span id="logo"><strong>Welcome </strong></span id="header"><strong>dev !</strong></span></a>

    </div>
    <ul class="nav navbar-nav navbar-right " >
            <li class="nav-custom"><a class="nav navbar-nav" href="/index"><span class="glyphicon glyphicon-home "> <span id="header"><strong>Home</strong></span></a></li>
            <li><a class="nav navbar-nav" href="/dashboard"><span class="glyphicon glyphicon-dashboard"> <span id="header"><strong>Dashboard</strong></span></a></li>
            <li><a class="nav navbar-nav" href="/about"><span class="glyphicon glyphicon-user"> <span id="header"><strong>About Us</strong></span></a></li>
            <li><a class="nav navbar-nav" href="/feedback"><span class="glyphicon glyphicon-pencil"> <span id="header"><strong>Feedback</strong></span></a></li>

            <li><a class="nav navbar-nav" href="/logout"><span class="glyphicon glyphicon-off"> <span id="header"><strong>Logout</strong></span></a></li>


    </ul>
      </div>
    </nav>







<div class="image-area">


<div class="container dash-container main-body" >
    <hr>
    <div class="row">
        <br>
        <hr >
        <br>
        <div class="col-md-12">
            <div class="jumbotron ">
                <h1 id="hdr">DASHBOARD</h1>
            </div>
        </div> 
    </div>






<div class="row" id="info">

    <a href="/dashboard"><span class="glyphicon glyphicon-backward" aria-hidden="true"></span></a>
</div>
<br><br>
<div class="row">
        <div class="col-md-12" id="info">

            <table class="table table-hover table-condensed table-bordered images-table" cellspacing="5" cellpadding="5">

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-18-39+PM_0.9997674822807312_0.0002324927772860974_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-18-39%20PM_0.9997674822807312_0.0002324927772860974_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-19-26+PM_0.0011277222074568272_0.9988722205162048_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-19-26%20PM_0.0011277222074568272_0.9988722205162048_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-19-47+PM_0.9632670283317566_0.03673300892114639_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-19-47%20PM_0.9632670283317566_0.03673300892114639_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>


                </tr>

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-20-31+PM_0.7819413542747498_0.21805864572525024_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-20-31%20PM_0.7819413542747498_0.21805864572525024_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-20-53+PM_0.03425532579421997_0.96574467420578_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-20-53%20PM_0.03425532579421997_0.96574467420578_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-23-59+PM_6.910012757543882e-07_0.9999992847442627_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-23-59%20PM_6.910012757543882e-07_0.9999992847442627_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>


                </tr>

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_02-24-21+PM_0.0027463394217193127_0.9972537159919739_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_02-24-21%20PM_0.0027463394217193127_0.9972537159919739_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_03-27-32+PM_0.8725430369377136_0.1274568885564804_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_03-27-32%20PM_0.8725430369377136_0.1274568885564804_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-23-40+PM_0.9983899593353271_0.0016100991051644087_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-23-40%20PM_0.9983899593353271_0.0016100991051644087_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>


                </tr>

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-24-43+PM_0.014673426747322083_0.9853265285491943_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-24-43%20PM_0.014673426747322083_0.9853265285491943_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-25-37+PM_0.028937892988324165_0.9710620641708374_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-25-37%20PM_0.028937892988324165_0.9710620641708374_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-26-08+PM_0.10836496949195862_0.8916350603103638_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-26-08%20PM_0.10836496949195862_0.8916350603103638_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>


                </tr>

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-26-56+PM_0.9980469942092896_0.0019529901910573244_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-26-56%20PM_0.9980469942092896_0.0019529901910573244_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-27-32+PM_0.0008696855511516333_0.9991303086280823_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-27-32%20PM_0.0008696855511516333_0.9991303086280823_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-28-29+PM_0.9541159868240356_0.04588397219777107_bio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-28-29%20PM_0.9541159868240356_0.04588397219777107_bio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>


                </tr>

                <tr class="image-hover">


                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-29-03+PM_0.0024711675941944122_0.9975288510322571_nonbio_.jpeg"><img src="/static/07-05-2018/07-05-18_04-29-03%20PM_0.0024711675941944122_0.9975288510322571_nonbio_.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>



                            <td style="width:10%;">
                                <a href="/display?folder=07-05-2018&amp;file=%2F07-05-18_04-29-25+PM_0.033340130001306534_0.9666599035263062_nonbio_+-+Copy+-+Copy+-+Copy+-+Copy+-+Copy+%282%29+-+Copy+-+Copy+-+Copy+-+Copy+-+Copy.jpeg"><img src="/static/07-05-2018/07-05-18_04-29-25%20PM_0.033340130001306534_0.9666599035263062_nonbio_%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20%282%29%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy%20-%20Copy.jpeg" alt="User Image" width="200" height="180"></a>
                                <br>

                            </td>




                </tr>

            </table>
        </div>
    </div>



</div>
</div>

<script type="text/javascript">

    var first_time = 0;
    var current_count = 0;
    var total_count = 0;

    function update(){
            if (window.first_time == 0){
                window.current_count = $('td').length;
                window.total_count = window.current_count;
                window.first_time = 1;
                //var txt = $("<p class='notify'></p>").text("No new images");
                $('body').append("<p class='notify'>No new images</p>");

            }
            else {

                window.total_count = $('td').length;
                if (window.total_count>window.current_count){
                    $('.notify').text(window.total_count-window.current_count + " images added !");
                    $('html, body').animate({scrollTop:$(document).height()}, 'slow');
                    //window.alert(total_count-current_count + ' images added !');
                    window.current_count = window.total_count;

                }
            }

    }
    setInterval(function(){ $('.image-area').load("/image/07-05-2018"); update(); }, 2000);
</script>




</body>
</html>

【问题讨论】:

  • 能否分享一下渲染后的 HTML
  • @AswinRamesh 请检查编辑 1

标签: javascript python jquery html ajax


【解决方案1】:

我检查了你的 javascript,你正在使用不存在的全局窗口变量而不是你预定义的局部变量。首先我认为你应该使用你定义的局部变量。

var first_time = 0;
var current_count = 0;
var total_count = 0;

function update(){
        if (first_time === 0){
            current_count = $('td').length;
            total_count = current_count;
            first_time = 1;
            //var txt = $("<p class='notify'></p>").text("No new images");
            $('body').append("<p class='notify'>No new images</p>");

        }
        else {

            total_count = $('td').length;
            if (total_count>current_count){
                $('.notify').text(total_count-current_count + " images added !");
                $('html, body').animate({scrollTop:$(document).height()}, 'slow');
                //alert(total_count-current_count + ' images added !');
                current_count = total_count;

            }
        }

}

我希望这会有所帮助。

我希望您在图像加载结束时尝试使用回调函数,因为更新函数可能会被调用两次,因为图像加载可能需要超过 2 秒才能加载其资源,从而导致 setInterval赶上它。

setInterval(function(){
    $('.image-area').load("{{ url_for('image',im=image_date) }}", function() {
       update();
    }); 
}, 2000);

【讨论】:

  • 它没有用。它继续执行 setInterval 代码两次,导致重复。
  • 不,它没有用。与以前相同的行为。另外,这些变量(first_time、total_count、current_count)不是已经是窗口对象的一部分了吗?
  • 不,他们不是,检查这个 developer.mozilla.org/en-US/docs/Web/API/Window 的窗口 api
  • 此 stackOverflow 链接另有说明 - stackoverflow.com/a/5786899/9122915
  • 我想它的更新函数被调用了两次而不是间隔,因为图像没有加载两次,我是对的吗? @BoudhayanDev
【解决方案2】:

将您设置的区间函数放入一个变量中,然后将该变量传递给 clearInterval() 函数,您的区间函数只执行一次

var myVar = setInterval(function(){ myTimer() }, 2000);

function myTimer() {

  $('.image-area').load("{{ url_for('image',im=image_date) }}"); 
  update();

}




   setInterval(function(){

     clearInterval(myVar);


}, 2000);

【讨论】:

  • 不,没用。我在 setInterval 语句之后添加了 clearInterval ,这导致了事件的完全阻塞,这很明显,因为我在声明它之后立即删除了它。我想要的行为是,偶数应该每 2 秒执行一次,而不是每 2 秒执行两次。
  • 不,它不起作用。事实上这一次,根本没有任何警报表明 setInterval 函数没有被调用。
【解决方案3】:
var myVar = setInterval(function(){ myTimer() }, 2000);
function myTimer() {
  $('.image-area').load("{{ url_for('image',im=image_date) }}"); 
  update();
}
setInterval(function(){
    clearInterval(myVar);
}, 2000);

试试这个:)

【讨论】:

  • 第一次加载页面时,它按预期工作。即没有重复,只有一条消息“没有新图像”。但随着新图像添加到后端,它不会显示新状态。这也是预期的,因为您在第一次执行后删除了间隔函数。所以,不是它不能完全工作
猜你喜欢
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多