javaScript运行机制 (同步与异步)的理解
javaScript的特点
javaScript的最大特点就是单线程。什么是单线程,可以理解为一条流水线,同一时间只能干一件事,不能同时做多件事。
为什么js是单线程,js的目的是为了与用户进行交互,以及操作dom。这一目的决定了js只能是单线程的,不然同一时间进行不同的dom操作(如增、删),那么以谁为主,就不好说了。
同步于异步
同步与异步的差异:在一条流水线(单线程)上各个任务执行的顺序不同。
一个简单的异步是setTimeout和setInterval函数(定时器),很常见其实这就是异步,他们的存在改变了js执行顺序。
例如:
console.log(1);
setTimeout(function(){
console.log(2);
},1000);
console.log(3);
很容易结果是:1 3 2
那么如果将定时器的时间设置为0,又是怎样的呢?
结果依然是 13 2
为什么出现这种情况,原因就是它是一个异步的定时事件,会被放到一个任务队列,会等没有放入任务队列的程序(主线程上的)执行完之后再执行。
任务队列里面放的是什么?放的就是setTimeout中的回调函数,。
于是任务分为两种:同步任务(synchronous)与异步任务(asynchronous).
同步任务: 在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务: 不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
具体来说异步运行机制:
(1) 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。
任务队列是一个事件队列,主线程读取"任务队列",就是读取里面有哪些事件。
“任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列”,等待主线程读取。
回调函数
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
事件循环:Event Loop
事件循环:JS 会创建一个类似于 while (true) 的循环,每执行一次循环体的过程称之为 Tick。每次 Tick 的过程就是查看是否有待处理事件,如果有则取出相关事件及回调函数放入执行栈中由主线程执行。待处理的事件会存储在一个任务队列中,也就是每次 Tick 会查看任务队列中是否有需要执行的任务。
参考:阮一峰老师的文章:http://www.ruanyifeng.com/blog/2014/10/event-loop.html
上一篇: 单实例Singleton设计模式
下一篇: Vue CLI