2018年07月06日
浏览器是一个事件驱动(event-driven)架构的软件。它的UI线程中会不断产生用户事件。但是处理事件的JavaScript是单线程执行的,这是一个浏览器环境下难以改变的现状(HTML5 Web Works没有从本质上改变这个模型)。这意味着:在JavaScript处理某个任务(执行某段代码)过程中,如果产生了用户事件,它不会立即被处理。那这种情况该怎么办呢?
但是,不仅用户事件可以被Event Loop机制处理,还能更多的东西是依赖这个机制的。
如果没有异步的理念,这个世界会完全不同:一个耗时的I/O操作(例如HTTP请求)会导致JavaScript执行线程等待,而后续的操作得不到执行。这种情况下,一个耗时的服务器端数据库操作http请求,会让JavaScript执行线程阻塞,浏览器将长期处于假死状态,在此期间,其他后续操作(包括用户的交互事件)得不到响应。
这便是异步的原理了。我们看到它同样依赖Event Loop的机制。
但是由于JavaScript执行线程的执行时间是不确定的,所以这个延时只是一个大体的值,它取决于JavaScript执行线程的执行时间。
但是不免奇怪的一点就是:JavaScript中怎么知道要执行的是哪个回调函数呢?答案就是:任务被放入任务队列的时候,该任务的回调函数会被注册(注册到什么地方?需要进一步探究)。这样,当特定任务完成的时候,任务结果和回调标记会返回给JavaScript执行线程,进入执行栈。
事件处理器和回调函数类似。但是特定的事件处理器在浏览器进入异步事件驱动阶段时就会针对特定的事件注册。当事件对象返回到JavaScript执行线程时,事件处理器也会同时进入执行栈中执行。
——本文并非原创,如有侵权请联系管理员删除。