JavaScript的运行机制简述

同步与异部

JavaScript是一门单线程语言。单线程就意味着,执行任务时需要一个接着一个执行,前一个执行结束才能继续执行下一个任务。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。JavaScript的开发者在开发时想到了这一点,将等待执行的任务挂起,继续执行后面的任务,也可以说在执行栈中需要等待的任务放到任务队列中,等到主线程执行完成后将任务栈中的完成的任务拿出来进行执行。这就是所谓的同步任务与异步任务。

JavaScript的运行机制简述

1、同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。

2、当Event Table中指定的事情完成时,会将这个函数移入Event Queue。

3、主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。

4、上述过程会不断重复,也就是常说的Event Loop(事件循环)。

5、我们不禁要问了,那怎么知道主线程执行栈为空啊?js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。

​JavaScript的宏任务与微任务

macro-task(宏任务):包括整体代码script,setTimeout,setInterval

micro-task(微任务):Promise,process.nextTick

不同类型的任务会进入对应的Event Queue。

事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。

示例

var promise=new Promise((resolve)=>{
            console.log(1)
            resolve()
        })
        setTimeout(()=>{
            console.log(2)
        })
        promise.then(()=>{
            console.log(3)
        })
        var promise2=getPromise()
        async function getPromise(){
            console.log(5)
            await promise;
            console.log(6)
            await promise2;
            console.log(7)
        }
        console.log(8)
        var promise3=new Promise((resolve)=>{
            console.log(10)
            resolve()
        })

这段代码中,输出顺序是什么?

JavaScript的运行机制简述

为什么会是这样?

因为以同步异步的方式来解释执行机制是不准确的,更加准确的方式是宏任务和微任务:    因此执行机制便为:执行宏任务 ===> 执行微任务 ===> 执行另一个宏任务 ===> 不断循环即:在一个事件循环中,执行第一个宏任务,宏任务执行结束,执行当前事件循环中的微任务, 执行完毕之后进入下一个事件循环中,或者说执行下一个宏任务

上一篇:3400位造型师,80位大数据科学家,这家美国女装公司这么做个性化定制


下一篇:前端学习的心路历程