关于JS执行机制
首先,我们要明白以下几点概念:
-
什么是单线程?
-
什么同步和异步?
-
同步任务和异步任务?
-
回调函数?
JavaScript语言的一大特点就是单线程。
(1). 单线程
所谓单线程,就是同一时间只能做一件事。
由于JS是为了处理页面中用户的交互以及操作DOM而产生的。如果JS的执行时间过长,单线程会造成页面渲染不连贯,导致页面渲染时会有阻塞的感觉。
为了解决此问题,利用多核CPU的计算能力,HTML5提出Web Work标准,允许JavaScript脚本创建多个线程。由此,JS出现了同步和异步的概念。
分析以下程序:
结果为:
如果按单线程的执行顺序:先打印 1—— 然后间隔1秒打印3 ——最后打印2
这样的执行会比较浪费时间,为了防止下一个任务等待上一个任务执行结束的时间过长,造成阻塞,所以JS出现了同步和异步的概念。
(2). 同步和异步
2.1 同步
前一个任务结束后再去执行后一个任务,程序的执行顺序与任务的排序是一致的、同步的。
2.2 异步
做一件事的同时可以去处理其他事情。
拿做饭举例:就像我们在烧水的时候,等待的同时可以去洗菜、切菜 ……
两者的本质区别:在这条流水线上各个流程的执行顺序不同
3.同步任务
同步任务都在主线程上执行,形成一个执行栈。
异步任务会被放到任务队列中等待同步任务执行完。
4.异步任务
异步任务有以下三种类型:
- 普通事件:click、resize等
- 资源加载:load、error等
- 定时器:包括setInterval、setTimeout等里面有回调函数
JS的异步是通过回调函数实现的,异步任务相关的回调函数会提交给异步进程处理,将任务添加到任务队列中(也称消息队列)
思考以下代码的执行结果:
这个定时器在0秒的时候就执行了,那结果是不是 1——3——2 呢?
当然不是!!
结果还是 1——2——3
为什么呢?
接下来,我们来了解JS是怎么执行的
(3). JS执行机制
执行步骤:
1.先执行执行栈中的同步任务
2.遇到异步任务时,先将异步任务(回调函数)放入任务队列中
3.一旦执行栈中所有的同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,
被读取的异步任务结束等待状态,进入执行栈,开始执行
主线程执行栈中有三个同步任务,定时器的fn是异步任务,放入了消息队列中。
先执行
console.log(1);
console.log(2);
后再去将任务队列中的回调函数fn调入执行栈再去执行
所以执行结果是:1——2——3
(4). 事件循环event loop
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行……
这种机制被称为事件循环