0

这段代码有什么问题?

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;
4

2 回答 2

1

当使用setTimeout或调用函数时setIntervalthis关键字失去其引用(函数在新上下文中调用)。this一般来说,将引用null(在严格模式下)或全局对象。
阅读MDN 上标题为“this”问题的部分以获取更多详细信息。基本上,您将一个函数的引用传递给window.setInterval,该函数在函数的上下文中调用该setInterval函数,这显然是window......由于全局对象显然没有timeAccept方法,因此您的 timout 循环运行一次,而不是20 次。就这么简单。
解决 IMO 问题的最快方法是使用闭包,并将整个上下文传递给区间函数:谢天谢地,这是一个简单的解决方法:

    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...
于 2013-03-12T16:49:21.570 回答
0

我解决了。

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);
    }

这种方式效果很好。

于 2013-03-13T11:45:40.793 回答