Javascript线程竞争条件
编辑:我找到了我在这里发布的原始YUI3问题的答案,但它导致了另一个问题,我想我应该在这里添加它,而不是开始一个新的线程。请向下滚动新问题(粗体) 原始问题: 我在YUI定义中创建JavaScript倒计时时遇到了一些问题,我猜这与对象范围有关。这是我的密码:Javascript线程竞争条件,javascript,dom-events,settimeout,race-condition,yui,Javascript,Dom Events,Settimeout,Race Condition,Yui,编辑:我找到了我在这里发布的原始YUI3问题的答案,但它导致了另一个问题,我想我应该在这里添加它,而不是开始一个新的线程。请向下滚动新问题(粗体) 原始问题: 我在YUI定义中创建JavaScript倒计时时遇到了一些问题,我猜这与对象范围有关。这是我的密码: YUI({combine: true, timeout: 10000}).use("node", function (Y) { var timer = new function(){}; Y.augment(timer,
YUI({combine: true, timeout: 10000}).use("node", function (Y) {
var timer = new function(){};
Y.augment(timer, Y.EventTarget);
timer.on('timer:down', function() {
Y.log('timer down event fired', 'event');
Y.Lang.later(1000, Y, timer_trigger());
});
timer.on('timer:end', function() {
Y.log('timer end event fired', 'event');
});
var timer_from;
function startTimer(seconds){ // start a coundown from seconds to 0
timer_from = seconds;
timer_trigger();
}
function timer_display(){
var mins = Math.floor(timer_from/60);
var secs = timer_from - mins*60;
var secsDisp = secs;
if(secs<10){
secsDisp = '0' + secs;
}
Y.one('#timer').set('innerHTML', mins + ':' + secsDisp);
}
function timer_trigger(){
Y.log('timer from is: '+timer_from);
if(timer_from > 0){
timer_from--;
timer_display();
if(timer_from > 0){
timer.fire('timer:down');
}
} else {
timer.fire('timer:end');
}
}
function initializePage(){
startTimer(900);
}
});
我查阅了比赛条件,但我不清楚这在我的情况下意味着什么,也不清楚对我的代码进行的看似微不足道的更改是如何解决我遇到的问题的。原来的问题已经回答了,但我想把这个问题转化为从答案中引出的问题
JavaScript中的线程是如何工作的,是什么导致了我的竞争状况,以及为什么代码中的微小更改修复了我的错误?问题不是竞争状况。额外调用setTimeout“修复”代码的原因是
timer\u trigger
中存在逻辑缺陷。考虑在调用函数时< <代码> TimeRe>从/<代码>中发生的情况。定时器:关闭和定时器:结束都不会被触发
function timer_trigger(){
Y.log('timer from is: '+timer_from);
if(timer_from > 0){ // Since timer_from is 1, the if block is entered
timer_from--; // timer_from is 0
timer_display();
if(timer_from > 0){ // This block is not entered, but it has no matching else
timer.fire('timer:down');
}
} else { // The matching if block was entered, so this is not
timer.fire('timer:end');
}
}
您添加了以下代码:
setTimeout(function(){
timer_trigger();
}, 1000);
这会导致再次调用
timer\u trigger
,其中timer\u from
已设置为0,从而允许执行else块。问题不是竞争条件。额外调用setTimeout“修复”代码的原因是timer\u trigger
中存在逻辑缺陷。考虑在调用函数时< <代码> TimeRe>从/<代码>中发生的情况。定时器:关闭和定时器:结束都不会被触发
function timer_trigger(){
Y.log('timer from is: '+timer_from);
if(timer_from > 0){ // Since timer_from is 1, the if block is entered
timer_from--; // timer_from is 0
timer_display();
if(timer_from > 0){ // This block is not entered, but it has no matching else
timer.fire('timer:down');
}
} else { // The matching if block was entered, so this is not
timer.fire('timer:end');
}
}
您添加了以下代码:
setTimeout(function(){
timer_trigger();
}, 1000);
这将导致再次调用timer\u trigger
,其中timer\u from
已设置为0,从而允许执行else块。还请注意
Y.Lang.later(1000, Y, timer_trigger());
立即执行timer_触发器,并稍后将返回值传递给Y.Lang。你可能是说
Y.Lang.later(1000, Y, timer_trigger);
还要注意
Y.Lang.later(1000, Y, timer_trigger());
立即执行timer_触发器,并稍后将返回值传递给Y.Lang。你可能是说
Y.Lang.later(1000, Y, timer_trigger);
作为将来的参考,当我的问题产生一个新线程时,我应该启动一个新线程吗?作为将来的参考,当我的问题产生一个新线程时,我应该启动一个新线程吗?这样会将函数传递给Y.Lang.later,它会在1000毫秒后执行,而不是函数的返回值?yep。上面所写的timer_触发器不包含return语句,因此默认情况下它返回undefined。对于Y.Lang.later(1000,Y,timer_trigger()),undefined作为一秒钟内执行的函数传递给Y.Lang.later。这转换为setTimeout(函数(){undefined.apply(Y);},1000);这是一个运行时错误。这将把函数传递给Y.Lang.later,它将在1000毫秒后执行它,而不是函数的返回值?是的。上面所写的timer_触发器不包含return语句,因此默认情况下它返回undefined。对于Y.Lang.later(1000,Y,timer_trigger()),undefined作为一秒钟内执行的函数传递给Y.Lang.later。这转换为setTimeout(函数(){undefined.apply(Y);},1000);这是一个运行时错误。哇,我很震惊我错过了。。。虽然我的计时器从未达到1,因为我总是在200左右停止。卢克的回答实际上解释了为什么我的定时器没有等1000毫秒才触发。哇,我很震惊我错过了这个。。。虽然我的计时器从未达到1,因为我总是在200左右停止。卢克的回答实际上解释了为什么我的定时器没有等待1000毫秒才触发。