找到 setTimeout() 中剩余的时间?
我正在编写一些与我不拥有的库代码交互的Javascript,并且无法(合理地)更改。它创建 Javascript 超时,用于显示一系列限时问题中的下一个问题。这不是真正的代码,因为它被完全混淆了。该库正在执行以下操作:
....
// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = setTimeout( showNextQuestion(questions[i+1]), t );
我想在屏幕上放置一个进度条,通过询问 setTimeout
创建的计时器,该进度条会向 questionTime * 1000
填充。唯一的问题是,似乎没有办法做到这一点。我是否缺少 getTimeout
函数?我能找到的关于 Javascript 超时的唯一信息仅与通过 setTimeout( function, time)
创建和通过 clearTimeout( id )
删除有关。
我正在寻找一个函数,它返回超时触发之前的剩余时间,或者返回超时调用后经过的时间。我的进度条代码如下所示:
var timeleft = getTimeout( test.currentTimeout ); // I don't know how to do this
var $bar = $('.control .bar');
while ( timeleft > 1 ) {
$bar.width(timeleft / test.defaultQuestionTime * 1000);
}
tl;dr: 如何查找 javascript setTimeout() 之前剩余的时间?
这是我现在使用的解决方案。我浏览了负责测试的库部分,并解读了代码(太糟糕了,而且违反了我的权限)。
// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = mySetTimeout( showNextQuestion(questions[i+1]), t );
这是我的代码:
// wrapper for setTimeout function mySetTimeout( func, timeout ) { timeouts[ n = setTimeout( func, timeout ) ] = { start: new Date().getTime(), end: new Date().getTime() + timeout t: timeout } return n; }
这在 IE 6 以外的任何浏览器中都可以正常工作。即使是最初的 iPhone,我希望事情能够异步。
I'm writing some Javascript that interacts with library code that I don't own, and can't (reasonably) change. It creates Javascript timeouts used for showing the next question in a series of time-limited questions. This isn't real code because it is obfuscated beyond all hope. Here's what the library is doing:
....
// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = setTimeout( showNextQuestion(questions[i+1]), t );
I want to put a progress bar onscreen that fills towards questionTime * 1000
by interrogating the timer created by setTimeout
. The only problem is, there seems to be no way to do this. Is there a getTimeout
function that I'm missing? The only information on Javascript timeouts that I can find is related only to creation via setTimeout( function, time)
and deletion via clearTimeout( id )
.
I'm looking for a function that returns either the time remaining before a timeout fires, or the time elapsed after a timeout has been called. My progress bar code looks like this:
var timeleft = getTimeout( test.currentTimeout ); // I don't know how to do this
var $bar = $('.control .bar');
while ( timeleft > 1 ) {
$bar.width(timeleft / test.defaultQuestionTime * 1000);
}
tl;dr: How do I find the time remaining before a javascript setTimeout()?
Here's the solution I'm using now. I went through the library section that's in charge of tests, and unscrambled the code (terrible, and against my permissions).
// setup a timeout to go to the next question based on user-supplied time
var t = questionTime * 1000
test.currentTimeout = mySetTimeout( showNextQuestion(questions[i+1]), t );
and here's my code:
// wrapper for setTimeout function mySetTimeout( func, timeout ) { timeouts[ n = setTimeout( func, timeout ) ] = { start: new Date().getTime(), end: new Date().getTime() + timeout t: timeout } return n; }
This works pretty spot-on in any browser that isn't IE 6. Even the original iPhone, where I expected things to get asynchronous.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
仅供记录,有一种方法可以获取node.js中剩余的时间:
打印:
这似乎在firefox中不起作用,但由于node.js是javascript,我认为此评论可能对寻找的人有帮助为节点解决方案。
Just for the record, there is a way to get the time left in node.js:
Prints:
This doesn't seem to work in firefox through, but since node.js is javascript, I thought this remark might be helpful for people looking for the node solution.
编辑:我实际上认为我做了一个更好的: https://stackoverflow.com/a/36389263/2378102
我写了这个函数,我经常使用它:
制作一个计时器:
所以如果你想要剩余时间,只需执行以下操作:
EDIT: I actually think I made an even better one: https://stackoverflow.com/a/36389263/2378102
I wrote this function and I use it a lot:
Make a timer:
So if you want the time remaining just do:
如果您无法修改库代码,则需要重新定义 setTimeout 以适合您的目的。以下是您可以执行的操作的示例:
这不是生产代码,但它应该使您走上正确的轨道。请注意,每次超时只能绑定一个侦听器。我还没有对此进行广泛的测试,但它可以在 Firebug 中使用。
更强大的解决方案将使用相同的包装 setTimeout 的技术,但使用从返回的 timeoutId 到侦听器的映射来处理每个超时的多个侦听器。您还可以考虑包装clearTimeout,以便在超时被清除时可以分离侦听器。
If you can't modify the library code, you'll need to redefine setTimeout to suit your purposes. Here's an example of what you could do:
This is not production code, but it should put you on the right track. Note that you can only bind one listener per timeout. I haven't done extensive testing with this, but it works in Firebug.
A more robust solution would use the same technique of wrapping setTimeout, but instead use a map from the returned timeoutId to listeners to handle multiple listeners per timeout. You might also consider wrapping clearTimeout so you can detach your listener if the timeout is cleared.
特定于服务器端 Node.js
上述内容对我来说都没有真正起作用,在检查超时对象后,一切看起来都与进程启动时相关。以下内容对我有用:
输出:
为简洁起见,编辑了输出,但这个基本函数给出了执行之前或执行之后的大致时间。正如其他人提到的,由于节点处理的方式,这些都不会是准确的,但是如果我想抑制不到 1 分钟前运行的请求,并且我存储了计时器,我不明白为什么这不会作为快速检查。在 10.2+ 中使用刷新计时器处理对象可能会很有趣。
Server side Node.js specific
None of the above really worked for me, and after inspecting the timeout object it looked like everything was relative to when the process started. The following worked for me:
Output:
Edited output for brevity, but this basic function gives a approximate time until execution or since execution. As others mention, none of this will be exact due to the way node processes, but if I want to suppress a request that was run less than 1 minute ago, and I stored the timer, I don't see why this wouldn't work as a quick check. Could be interesting to juggle objects with refreshtimer in 10.2+.
更快、更简单的方法:
您可以通过以下方式获取剩余时间:
A quicker, easier way:
You can get the time remaining with:
Javascript 的事件堆栈并不像你想象的那样运作。
创建超时事件后,它会被添加到事件队列中,但在该事件被触发时,其他事件可能会优先,从而延迟执行时间并推迟运行时间。
示例:您创建一个延迟 10 秒的超时,以向屏幕发出提醒。它将被添加到事件堆栈中,并在所有当前事件被触发后执行(导致一些延迟)。然后,当超时处理完毕后,浏览器仍然继续捕获其他事件并将它们添加到堆栈中,这会导致处理进一步延迟。如果用户单击或进行大量 ctrl+打字,则他们的事件优先于当前堆栈。你的 10 秒可以变成 15 秒,甚至更长。
话虽这么说,有很多方法可以伪造已经过去了多少时间。一种方法是将 setTimeout 添加到堆栈后立即执行 setInterval。
示例:执行 10 秒延迟的设置超时(将该延迟存储在全局中)。然后执行每秒运行一次的 setInterval 将延迟减去 1 并输出剩余的延迟。由于事件堆栈如何影响实际时间(如上所述),这仍然不准确,但确实给出了计数。
简而言之,没有真正的方法来获取剩余时间。只有尝试向用户传达估计值的方法。
Javascript's event stacks don't operate how you would think.
When a timeout event is created, it is added to the event queue, but other events may take priority while that event is being fired, delay the execution time and postponing runtime.
Example: You create a timeout with a delay of 10 seconds to alert something to the screen. It will be added to the event stack and will be executed after all current events are fired (causing some delay). Then, when the timeout is processed, the browser still continues to capture other events add them to the stack, which causes further delays in the processing. If the user clicks, or does a lot of ctrl+typing, their events take priority over the current stack. Your 10 seconds can turn into 15 seconds, or longer.
That being said, there are many ways to fake how much time has passed. One way is to execute a setInterval right after you add the setTimeout to the stack.
Example: Perform a settimeout with a 10 second delay (store that delay in a global). Then perform a setInterval that runs every second to subtract 1 from the delay and output the delay remaining. Because of how the event stack can influence actual time (described above), this still won't be accurate, but does give a count.
In short, there is no real way to get the remaining time. There are only ways to try and convey an estimate to the user.
我在这里停下来寻找这个答案,但过度思考了我的问题。如果您在这里是因为您只需要在 setTimeout 正在进行时跟踪时间,那么还有另一种方法:
I stopped by here looking for this answer, but was overthinking my problem. If you are here because you just need to keep track of time while you're setTimeout is in progress, here's another way to do it:
您可以修改
setTimeout
将每个超时的结束时间存储在地图中,并创建一个名为getTimeout
的函数来获取某个 id 超时的剩余时间。这是super的解决方案,但我修改了它以使用稍微更少的内存
用法:
这是此
getTimeout
的缩小版本 IIFE:我希望这对您和我一样有用! :)
You can modify
setTimeout
to store each timeout's end time in a map and create a function calledgetTimeout
to get the time left for a timeout with a certain id.This was super's solution, but I modified it to use slightly less memory
Usage:
Here's a minified version of this
getTimeout
IIFE:I hope this is as useful to you as it was for me! :)
不,但是您可以在函数中为动画设置自己的 setTimeout/setInterval 。
假设您的问题如下所示:
您的动画将由这两个函数处理:
No, but you can have your own setTimeout/setInterval for animation in your function.
Say your question looks like this:
And your animation will be handled by these 2 functions:
问题已经得到解答,但我会补充一点。我刚刚想到的。
在
recursion
中使用setTimeout
如下:我想代码是不言自明的
Question has already been answered but I will add my bit. It just occured to me.
Use
setTimeout
inrecursion
as follows:I guess the code is self explanatory
检查此项:
制作计时器:
获取剩余:
清除超时
Check this one:
Make a timer:
Get remain:
Clear timeout
对于任何需要钩子的人,请检查一下 - 应该是非常不言自明的。
请注意,elapsed 是一个内部状态变量,如果传递到钩子外部将是不正确的!
For anyone in need of a hook, check this out - should be pretty self explanatory.
Note that elapsed is an internal state variable that if passed outside of the hook will be incorrect!
我创建了一个类,允许您暂停和恢复超时和间隔,希望它有帮助!
I created a class to allow you to pause and resume timeouts and intervals, hope it helps!