Javascript 并发模型与事件循环

JS中的线程

我们常说“JavaScript是单线程的”。

所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。不妨叫它主线程。

但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等。这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分。不妨叫它们工作线程

消息队列模型

a2a9a325-28b9-4f02-a494-c2e69ffeda94

setTimeout 函数会在一个时间段过去后在队列中添加一个消息

(function () {

  console.log('this is the start');

  setTimeout(function cb() {
    console.log('this is a msg from call back');
  });

  console.log('this is just a message');

  setTimeout(function cb1() {
    console.log('this is a msg from call back1');
  }, 0);

  console.log('this is the  end');

})();

// "this is the start"
// "this is just a message"
// "this is the end"
// "this is a msg from call back"
// "this is a msg from call back1"

事件

72b0405e-cf5a-41f8-84f5-de9d5cff096e

异步过程的回调函数,一定不在当前这一轮事件循环中执行。消息队列中的每条消息实际上都对应着一个事件。

上文中一直没有提到一类很重要的异步过程:DOM事件

var button = document.getElement('#btn');
button.addEventListener('click', function(e) {
    console.log();
});

从异步过程的角度看,addEventListener函数就是异步过程的发起函数,事件监听器函数就是异步过程的回调函数。事件触发时,表示异步任务完成,会将事件监听器函数封装成一条消息放到消息队列中,等待主线程执行。

事件的概念实际上并不是必须的,事件机制实际上就是异步过程的通知机制。我觉得它的存在是为了编程接口对开发者更友好。

参考

参考资料:JavaScript:彻底理解同步、异步和事件循环(Event Loop)

Show Comments