1. JavaScript 是一门单线程语言,这是由于其工作场景导致的,在浏览器中,如果 JavaScript 是多线程语言,那么两个线程要做的事情分别为:A:我要删除元素 div,B:我要给 div 添加一个类,此时如果是多线程同时工作就会出现矛盾问题。
2. 由以上一个简单的解释,我们知道 JavaScript 必须是单线程的,那么单线程意味着你的所有需要执行的任务需要排队,当前一个任务执行完毕后,下一个任务才可以被执行。那么这里又会出现一个问题,如果其中一个任务执行时间过长,那么后面的任务将会一直等待这个任务执行完毕,这是一种极大的效率浪费,我们应当去避免这个问题。比如在 Ajax 网络请求过程中,需要耗费很长时间,那么我们可不可以把这个请求任务挂起来,让它先慢慢的去执行,我们先去执行下一个任务,等到请求返回数据我们在回过头来处理请求结果,答案是可以的。
3. 由此我们引出 同步 synchronous 和 异步 asynchronous 的概念,同步就是任务在主线程上按照次序一个个执行,前一个执行完后一个才能继续执行,而异步不进入主线程,而是进入“任务队列”,只有任务队列中的异步任务可以被执行了,且主线程任务全部执行完毕,才会将其调入主线程执行。
简单总结一下步骤就是:【1】同步任务全部进入主线程,依次执行。
【2】异步任务等进入任务队列,只要异步任务可以被执行了,就会在任务队列中放置一个事件。
【3】主线程的同步任务全部执行完毕,来任务队列查看是否有事件可以执行,若有,则将其放入主线程开始执行。
【4】以上三步重复执行.
此图转载自知乎:https://zhuanlan.zhihu.com/p/87684858 在事件循环中,每进行一次循环叫做一个 tick.
4. 宏任务和微任务:
由于第一次宏任务执行的是 script 整体代码,因此也有很多人认为先执行微任务后执行宏任务,即他们把执行 script 整体代码忽略掉了,这种理解某种层面上也是正确的.