Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在闭包中包装时的clearTimeout?_Javascript_Closures - Fatal编程技术网

Javascript 在闭包中包装时的clearTimeout?

Javascript 在闭包中包装时的clearTimeout?,javascript,closures,Javascript,Closures,已更新 HTML 使用Knockout创建通知组件 ko.components.register('notification', { viewModel: function(params) { var data = params.data; /* set the message to the data.message */ this.message = data.message || null; /* removes t

已更新

HTML

使用Knockout创建通知组件

ko.components.register('notification', {
    viewModel: function(params) {
        var data = params.data;

        /* set the message to the data.message */
        this.message = data.message || null;

        /* removes the notification from the array */
        this.removeNotification = function() {
            appViewModel.notificationArray.remove(data);
        };

        /* create timer to remove notification after 5s */
        /* need to wrap in closure so that inside of the setTimeout it can know about the data object needed to send to the remove() command */
        this.timer = function(obj, timeoutLength) {
            /* adding return statement per suggestion on Stack Overflow */
            return setTimeout(function() {
                appViewModel.notificationArray.remove(obj);
            }, timeoutLength);
        };

        this.timer(data, 5000);

       /* log will output function structure */
       /* clearTimeout will not work */
        this.hover = function() {
            console.log(this.timer);
            clearTimeout(this.timer);
        }

    },
    template: '<div class="notification show-notification" data-bind="event: { mouseover: hover, fastClick: hover }">'
        +'<div class="notifications-close clickable right" data-bind="fastClick: removeNotification"><span class="icon icon-x"></span></div>'
        +'<div class="notification-text" data-bind="text: message"></div>'
        +'</div>'
});
ko.components.register('notification'){
viewModel:函数(参数){
var数据=参数数据;
/*将消息设置为data.message*/
this.message=data.message | | null;
/*从阵列中删除通知*/
this.removeNotification=函数(){
appViewModel.notificationArray.remove(数据);
};
/*创建计时器以在5s后删除通知*/
/*需要在闭包中进行包装,以便在setTimeout中可以知道发送到remove()命令所需的数据对象*/
this.timer=函数(obj,timeoutLength){
/*在堆栈溢出时为每个建议添加返回语句*/
返回setTimeout(函数(){
appViewModel.notificationArray.remove(obj);
},超时长度);
};
这个计时器(数据,5000);
/*日志将输出函数结构*/
/*clearTimeout将不起作用*/
this.hover=函数(){
console.log(this.timer);
clearTimeout(this.timer);
}
},
模板:“”
+''
+''
+''
});
更新以反映工作解决方案

JS

appViewModel.notificationArray=ko.observableArray([
{消息:'测试1'},
{消息:“测试2'}
]);
ko.组件登记簿(‘通知’{
viewModel:函数(参数){
var数据=参数数据;
this.message=data.message | | null;
this.timer=null;
this.removeNotification=函数(){
appViewModel.notificationArray.remove(数据);
};
this.timer=(函数(self){
返回setTimeout(函数(){
自我重塑();
}, 5000);
})(本条);
this.hover=函数(){
clearTimeout(this.timer);
};
this.restart=函数(){
this.timer=(函数(self){
返回setTimeout(函数(){
自我重塑();
}, 5000);
})(本条);
}
},
模板:“”
+''
+''
+''
});

您没有将
此.timer
设置为
设置超时的结果。也许您需要
返回setTimeout


现在是第二个问题
this.hover
this
一起作为其他内容调用。这已经在许多其他问题中得到了解决。一种方法是在正确的
this
的正确范围内使用
var self=this
,或者我当前的首选项是
this.hover=function(){…}.bind(this)

您没有将
此.timer
设置为
setTimeout
的结果。也许您需要
返回setTimeout

现在是第二个问题
this.hover
this
一起作为其他内容调用。这已经在许多其他问题中得到了解决。一种方法是在正确的
this
的正确范围内使用
var self=this
,或者我当前的首选项是
this.hover=function(){…}.bind(this)

编辑:此答案在发布已接受答案之前开始。所发现的问题相似,但解决方案略有不同

1) 您可以将整个
this.timer=
语句替换为

var timerId =  setTimeout(function(){
    appViewModel.notificationArray.remove(data), 5000);
    timerId = 0;  // timer finished
};
然后timerId在传递给setTimeout(也称为“闭包”)的非规则函数的函数范围内,在这里它和
数据都可以看到

2) 悬停函数也可以使用闭包

this.hover = function() {
    console.log("timer " + timerId ? timerId : "finished");
    if( timerId)
        clearTimeout(timerId); 
}
编辑:此答案在已接受的答案发布之前开始。所发现的问题相似,但解决方案略有不同

1) 您可以将整个
this.timer=
语句替换为

var timerId =  setTimeout(function(){
    appViewModel.notificationArray.remove(data), 5000);
    timerId = 0;  // timer finished
};
然后timerId在传递给setTimeout(也称为“闭包”)的非规则函数的函数范围内,在这里它和
数据都可以看到

2) 悬停函数也可以使用闭包

this.hover = function() {
    console.log("timer " + timerId ? timerId : "finished");
    if( timerId)
        clearTimeout(timerId); 
}

你在哪里附加悬停处理程序?你在哪里附加悬停处理程序?除非你的用例比示例更复杂,否则闭包中真的没有任何意义,你可以只使用
this.timer=setTimeout(…)
@Daniel我已经更新了我的OP以反映你的建议。我可能实现错了,但实际上它的功能并没有比以前更好。@DanielA.White谢谢,我在我的OP中添加了一个部分,显示了最终的工作代码。你能给我解释一下为什么这样:this.timer=(函数(self){returnsettimeout(函数(){self.removeNotification();},5000);})(this);不同于:this.timer=function(self){return setTimeout(function(){self.removeNotification();},5000);};这个计时器(这个);除非您的用例比示例更复杂,否则闭包实际上没有任何意义,您可以使用
this.timer=setTimeout(…)
@Daniel我已经更新了我的OP以反映您的建议。我可能实现错了,但实际上它的功能并没有比以前更好。@DanielA.White谢谢,我在我的OP中添加了一个部分,显示了最终的工作代码。你能给我解释一下为什么这样:this.timer=(函数(self){returnsettimeout(函数(){self.removeNotification();},5000);})(this);不同于:this.timer=function(self){return setTimeout(function(){self.removeNotification();},5000);};这个计时器(这个);
this.hover = function() {
    console.log("timer " + timerId ? timerId : "finished");
    if( timerId)
        clearTimeout(timerId); 
}