Event Loop探究

本节主要讲述Event Loop探究

JS是单线程的

JavaScript语言最大特点就是单线程,但是这里的单线程指的是主线程是单线程的。那为什么js要单线程呢? 因为,JS主要用于操作DOM,如果是有两个线程,一个在DOM上添加内容,一个在DOM上删除内容,此时浏览器该以哪个为准呢? 所以为了避免复杂性,JavaScript从诞生起就是单线程的。

同步和异步

同步和异步关注的是消息通知机制

  • 1)同步在发出调用后,没有结果前是不返回的,一旦调用返回,就得到返回值。调用者会主动等待这个调用结果。
  • 2)异步是发出调用后,调用者不会立刻得到结果,而是被调用者通过状态或回调函数来处理这个调用。

任务队列

  • 因为JavaScript是单线程的。就意味着所有任务都需要排队,前一个任务结束,后一个任务才能执行。前一个任务耗时很长,后一个任务也得一直等着。但是IO设备(比如ajax网络请求)很慢,CPU一直初一显得状态,这样就很不合理了。
  • 所以,其实主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。于是有了同步任务异步任务

同步任务是指在主线程上执行的任务,只有前一个任务执行完毕,下一个任务才能执行。 异步任务是指不进入主线程,而是进入任务队列(task queue)的任务,只有主线程任务执行完毕,任务队列的任务才会进入主线程执行。

从上图看到:

  1. 主线程运行的时候产生堆(heap)和栈(stack)
  2. 栈中的代码调用各种外部API,它们在”任务队列”中加入各种事件(click,load,done)
  3. 只要栈中的代码执行完毕,主线程就会去读取”任务队列”,将队列中的事件放到执行栈中依次执行。
  4. 主线程继续执行,当再调用外部API时又加入到任务队列中,等主线程执行完毕又会接着将任务队列中的事件放到主线程中。
  5. 上面整个过程是循环不断的。