clearInterval函数不能与backbone.js一起工作

clearInterval function is not working with backbone.js

本文关键字:js 一起 工作 backbone 函数 不能 clearInterval      更新时间:2023-09-26

这段代码有什么问题?

setInterval()不停止。这是一个无限循环。

这是视图的代码。

var chat = require('core/chat');
var Backbone = require('backbone');
var $ = require('jquery');
var agentOfferTemplate = require('hbs!templates/agent-offer');
var contador = 20;
var intervalID;
AgentOfferView = Backbone.View.extend({

    template : agentOfferTemplate,

    initialize : function() {
        this.timeAccept();
    }, 

    render : function() {
            this.$el.append(this.template(this.model.toJSON()));
            return this;
        },
    timeAccept : function(){ 
        if (contador > 0){
            $('#tempo').html(contador); 
            $('#barra-interna').css('width', contador * 10);
            intervalID = setInterval(this.timeAccept, 1000);                
            contador = contador - 1;
        }
        else {
            window.clearInterval(intervalID);
            intervalID = null;
            $('#countdown-container').hide();
    contador = 20;                 
        }
    }
});
 return AgentOfferView;

当使用setTimeoutsetInterval调用函数时,this关键字将失去其引用(该函数将在新的上下文中调用)。一般来说,this将引用null(在严格模式下)或全局对象。
请阅读MDN上题为"this"问题的部分了解更多细节。基本上,你将一个函数的引用传递给window.setInterval,它在setInterval函数的上下文中调用该函数,这显然是window……由于全局对象显然没有timeAccept方法,所以超时循环只运行一次,而不是20次。就是这么简单。
在我看来,解决这个问题最快的方法是使用闭包,并将整个上下文传递给interval函数:值得庆幸的是,这是一个简单的修复:

    timeAccept : function()
    { 
        if (contador > 0)
        {
            $('#tempo').html(contador);
            $('#barra-interna').css('width', contador * 10);
            intervalID = setTimeout((function(context)
            {//pass current this reference to closure
                return function()
                {//instead of this, use context
                        setInterval(context.timeAccept, 1000);
                };
            }(this)),1000);
            contador--;
        }
        else
        {
            clearTimeout(intervalID);
            intervalID = null;
            $('#countdown-container').hide();
            contador = 20;                 
    }

间隔是指每X毫秒一次又一次地调用给定函数。查看您的代码,您可能希望使用setTimout,它只调用该函数一次。
现在,您创建了20个间隔,每个间隔每秒调用同一个函数。即使contador >= 0,间隔也会继续调用函数。

考虑以下例子:

var intervalId = setInterval(function()
{
    console.log('You''ll see this appear every second');
    console.log('This interval has an ID, and it''s: ' + intervalId);
},1000);
var timeout = setTimeout(function()
{
    console.log('This will only appear once, after 1000ms');
    console.log('A timeout has an ID, too: ' + timeout);
},1000);
//using the ID's you can cancel both the timeout and the interval using these lines:
clearInterval(intervalId);
clearTimeout(timeout);//usefull if you want to cancel the delayed function call...

我解决了。

timeAccept : function(){ 
        var intervalId = setInterval(
            function(){
                if (contador > 0){
                    $('#tempo').html(contador); 
                    $('#barra-interna').css('width', contador * 10);
                    contador--;
                }else{
                    clearInterval(intervalId);
                    $('#countdown-container').hide();
                    contador = 20;
                }
            }, 1000);
    }

这个方法很好。