清除函数中的 'looped' 超时关闭 - 如何 return 我能够清除它的间隔 ID
Clear 'looped' timeout closed in function - how to return id of interval that I would have ability to clear it
我的 Class 中有两个函数。首先触发超时并循环它(像间隔一样工作),然后是 clearTimeout。我的问题是,clearTimeout 不起作用。我该如何解决?
this.startMove = function() {
setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.startMove());
}
例如我想运行点击这些功能。
您需要将超时分配给处理程序:
this.startMove = function() {
self.timeout = setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
编辑
正如 michalgrzasko 提到的,上面的代码不起作用。原因是句柄分配给了错误的超时函数。外层超时只设置一次,而内层超时是在递归循环中调用的,所以就是需要清除的超时。
this.startMove = function() {
setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
self.handle = setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
但是
同样,正如 michalgrzasko 和其他几个人指出的那样,更好的解决方案是使用 setInterval,因为它更容易阅读,因此更安全:
this.startMove = function() {
self.moveInterval = setInterval(function handler() {
self.moveMonster(moveMonsterCallback);
}, this.speed);
};
this.stopMove = function() {
clearInterval(self.moveInterval);
}
让我知道这是否适合您:
this.startMove = function() {
self.timeout = setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
self.startMove();
}, self.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
所以基本上我重复使用了@Michael Horn 的解决方案。而且,我很乐意将此答案用作他编辑后的答案(如果问题解决了)。
如果您使用 setTimeout 或 setInterval 并希望能够取消它们,您需要将此函数的 return值保存在一个变量中。 return-value 是一个处理程序,可以在 clearTimeout 或 clearInterval 中使用。
在这种情况下,如果 moveMonster 函数的时间消耗比 this.speed 少,setInterval 会更容易。
this.startMove = function() {
this.startMove.intervalHandler = setInterval(function handler() {
self.moveMonster(moveMonsterCallback);
}, this.speed);
};
this.stopMove = function() { clearInterval(this.startMove.intervalHandler); }
我更喜欢用函数作用域来保存像Handler这样的东西。如果您不喜欢它,请使用父范围或上下文
如果使用 setTimeout 而不是 setInterval 很重要,您可以在其他答案中找到解决方案。完全相同:保存 setTimeout 的 return 值,稍后使用 clearTimeout。
如果动画结束时应该调用 moveMonsterCallback,请查看承诺而不是回调。通过回调,您可以快速定位,很难跟踪调用。
关于动画的一句话:它们很棘手!不要使用设置超时。最好在 window 对象上调用 requestAnimationFrame。
function step(timestamp) {
if (!step.startTime) step.startTime = timestamp;
var delta = step.getDelta(timestamp);
// do the calculations of how far you have to move the monster in this time range
// move the monster...
...
// animation is stopped? If not: We want to animate another timeframe
if (!step.stopped) {
window.requestAnimationFrame(step);
}
}
step.startTime = null;
step.stopped = false;
step.getDelta = (timestamp)=>timestamp-step.startTime;
function stopMove() {
step.stopped = true;
}
window.requestAnimationFrame(step);
此解决方案提供了更好的结果,因为它与 setTimeout 的精度无关。它适用于时差
我的 Class 中有两个函数。首先触发超时并循环它(像间隔一样工作),然后是 clearTimeout。我的问题是,clearTimeout 不起作用。我该如何解决?
this.startMove = function() {
setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.startMove());
}
例如我想运行点击这些功能。
您需要将超时分配给处理程序:
this.startMove = function() {
self.timeout = setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
编辑
正如 michalgrzasko 提到的,上面的代码不起作用。原因是句柄分配给了错误的超时函数。外层超时只设置一次,而内层超时是在递归循环中调用的,所以就是需要清除的超时。
this.startMove = function() {
setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
self.handle = setTimeout(handler, self.speed);
}, this.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
但是
同样,正如 michalgrzasko 和其他几个人指出的那样,更好的解决方案是使用 setInterval,因为它更容易阅读,因此更安全:
this.startMove = function() {
self.moveInterval = setInterval(function handler() {
self.moveMonster(moveMonsterCallback);
}, this.speed);
};
this.stopMove = function() {
clearInterval(self.moveInterval);
}
让我知道这是否适合您:
this.startMove = function() {
self.timeout = setTimeout(function handler() {
self.moveMonster(moveMonsterCallback);
self.startMove();
}, self.speed);
};
this.stopMove = function() {
clearTimeout(self.timeout);
}
所以基本上我重复使用了@Michael Horn 的解决方案。而且,我很乐意将此答案用作他编辑后的答案(如果问题解决了)。
如果您使用 setTimeout 或 setInterval 并希望能够取消它们,您需要将此函数的 return值保存在一个变量中。 return-value 是一个处理程序,可以在 clearTimeout 或 clearInterval 中使用。
在这种情况下,如果 moveMonster 函数的时间消耗比 this.speed 少,setInterval 会更容易。
this.startMove = function() {
this.startMove.intervalHandler = setInterval(function handler() {
self.moveMonster(moveMonsterCallback);
}, this.speed);
};
this.stopMove = function() { clearInterval(this.startMove.intervalHandler); }
我更喜欢用函数作用域来保存像Handler这样的东西。如果您不喜欢它,请使用父范围或上下文
如果使用 setTimeout 而不是 setInterval 很重要,您可以在其他答案中找到解决方案。完全相同:保存 setTimeout 的 return 值,稍后使用 clearTimeout。
如果动画结束时应该调用 moveMonsterCallback,请查看承诺而不是回调。通过回调,您可以快速定位,很难跟踪调用。
关于动画的一句话:它们很棘手!不要使用设置超时。最好在 window 对象上调用 requestAnimationFrame。
function step(timestamp) {
if (!step.startTime) step.startTime = timestamp;
var delta = step.getDelta(timestamp);
// do the calculations of how far you have to move the monster in this time range
// move the monster...
...
// animation is stopped? If not: We want to animate another timeframe
if (!step.stopped) {
window.requestAnimationFrame(step);
}
}
step.startTime = null;
step.stopped = false;
step.getDelta = (timestamp)=>timestamp-step.startTime;
function stopMove() {
step.stopped = true;
}
window.requestAnimationFrame(step);
此解决方案提供了更好的结果,因为它与 setTimeout 的精度无关。它适用于时差