JavaScript 是单线程的,可以通过浏览器或者 Node.js 的运行时环境实现异步编程。JavaScript的 setTimeout
函数可以让某个 callback 定时执行。
以 setTimeout
为例,在 Node.js 的实现里:
-
setTiemout(func, 1000)
在调用栈里执行 setTimeout
立即返回
- 随后它会把 func 放入对应任务队列(这里应该是Timer任务队列)
- 1s内,event loop 轮询 消息队列 获取事件消息,当消息队列没有事件时,消息队列阻塞,所以不会占用cpu时间
- 1s后,
event loop
从消息队列获得计时结束的事件消息,从对应任务队列中取出 func 并执行
Emacs 也提供了一个定时器api,run-at-time
,我发现它的 timer-list
是一个 C 变量,猜想底层是不是也是使用 event loop
的方式实现的?
参考资料:
deferred.el 也是利用 run-at-time
来实现异步的。
也有人按照 JavaScript 标准异步接口 Promise 写了对应 Emacs 的库,不过是用多进程的方式实现的。
emacs-promise
硬件有定时器,通过中断通知操作系统,系统再调用应用程序的回调函数。
我猜是这样吧