如何在javascript解释器或定时器中实现setTimeout?

alv*_*tar 15 implementation interpreted-language

在javascript或任何其他解释语言中实现了一段时间之后调用的函数如何?

换句话说,javascript解释器中是否有一个循环,它一直检查定时器列表,或者操作系统是否有任何特定的方式来处理它?

谢谢

Evg*_*nev 9

John Resig的博客中有一个很好的描述

  • 那篇博文很适合分析javascript执行队列,但并没有真正回答这个问题:当计时器触发时,东西如何进入队列?似乎执行队列不是一个调度程序,你可以在其中放置要在以后执行的东西,它们会在有空间时立即执行.你知道实际的计时器是如何工作的,它会触发执行队列的追加吗?我想在linux envs中它可能就像ev http://linux.die.net/man/3/ev (5认同)

All*_*ind 2

您维护一个允许存储(超时、回调)的排序数据结构(例如优先级队列)。这使您可以快速确定下一次超时的时间。关键方面是我们如何等待,以及如何中断等待以安排新的回调。

  1. 您可以通过sleep(3) 在线程中等待,完成后调用回调。当您需要安排新的(超时、回调)时,向线程发送signal(2) 或(3)。pthread_cond_signal

  2. 与上面类似,但是使用pthread_cond_timedwait(2) ,并且当发生超时或条件变量触发以安排新的回调时,线程将被唤醒。

  3. 您可以安排alarm(2) 并继续您正在执行的任何其他任务。当警报响起时,它会向您的进程发送信号,您可以在方便时调用回调。要安排新的超时,您可以设置一个新的闹钟,该闹钟将取消旧的闹钟。

  4. 您使用select(2)/ poll(2)/ epoll_*(2) 并超时。当超时发生时,您调用回调。要安排一个新的回调,您需要向管道写入一个字节,该字节专门用于让 select/poll/epoll 返回,以便您安排一个新事件。例如,chrome/node/v8 使用仅包装在兼容层中的此方法(请参阅Node.js 中如何实现 setTimeout)。

  5. 与上面类似,但您可以使用timerfd_create(2) 作为文件描述符来传递时间到期时间,而不是使用超时参数。