JavaScript运行机制的示例分析

  介绍

这篇文章将为大家详细讲解有关JavaScript运行机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

说JavaScript运行机制之前,先看一段代码:

console.log (1)   Promise.resolve ()。然后(函数(){   console.log (2)   })   新的承诺(函数(解决,拒绝){   console.log (3)   解决()   })。然后(函数(){   console.log (4)   setTimeout(函数(){   console.log (5)   })   })   console.log (6)   setTimeout(函数(){   Promise.resolve ()。然后(函数(){   console.log (7)   setTimeout(函数(){   console.log (8)   })   })   })

如果你看到这段代码,并知道正确的输出顺序。那说明你对这块掌握的差不多了。(直接翻到最后看结果)

好,言归正传。

在说是怎么运行的之前,先看几个概念。

<强>执行上下文(执行上下文)

执行上下文简单来说就是一个执行环境。它有全局环境,函数环境和eval函数环境之分。它会在javascript引擎执行你的脚本的时候去创建。

<强>执行栈(执行堆栈)

执行栈也就是常说的调用栈,它是一种拥有后进先出(后进先出)的数据结构。它会存储代码运行时创建的执行上下文

<强>微任务(微任务)与宏任务(宏观任务)

javasript中的任务分为微任务和宏任务两种,这两种任务的执行时机是不同的,因此区分js中哪些是宏任务,哪些是微任务则十分重要。我们常见的宏任务有:脚本任务,setTimeout、ajax等,常见的微任务比较典型的是:Promise.resolve()()的过程。nextTick, MutationObserver等。

<强>事件循环(事件循环)

js是单线程的,也就是说它一次仅能处理一个任务。但js所在的宿主环境,也就是我们所说的浏览器并不是单线程的(这里宿主环境仅讨论浏览器)。它在遇到一些任务时,比如说setTimeout,事件监听器等。它会告诉浏览器:老兄帮个忙,事成后通知我一声,小弟我先干别的事去了。浏览器会回应说:交给我吧,小老弟,事成后我放到任务队列,自己去取啊。于是,js开始执行脚本任务,执行完了就开始检查有没有微任务啊,没有的话就从任务队列开始取宏任务执行,每执行完一次宏任务,就去看看有没有微任务,有的话就执行完成,再执行宏任务,如此往复。如下:

了解了这几个概念,再来看看javascript是怎么执行代码的就比较轻松愉快了。开始吧

console.log (1)      Promise.resolve ()。然后(函数(){   console.log (2)   })      新的承诺(函数(解决,拒绝){   console.log (3)   解决()   })。然后(函数(){   console.log (4)   setTimeout(函数(){   console.log (5)   })   })      console.log (6)      setTimeout(函数(){   Promise.resolve ()。然后(函数(){   console.log (7)   setTimeout(函数(){   console.log (8)   })   })   })

js引擎在执行这段代码的时候,首先将全局执行上下文压入栈中:

然后呢,在执行的时候会碰到console.log函数,将它压入栈中:

这个时候,直接执行控制台函数,并输出1。然后控制台函数出栈:

继续往下执行,碰到了Promise.resolve()(),先将Promise.resolve()()压入栈中(这里,我为了图方便就把它看成整体了,不然得画很多图)。

 JavaScript运行机制的示例分析

然后执行Promise.resolve()(),前面说过,这个然后()函数是个微任务,它会将传入给它的回调函数加入到微任务队列中。

然后Promise.resolve()()就出栈了。

接着执行,遇到承诺的构造函数,这个构造函数是一个宏任务,会直接将传递给它的函数压入栈中。

 JavaScript运行机制的示例分析“> <br/>执行控制台函数并输出3,执行完,安慰函数出栈,接着执行解决()函数,并出栈。<br/>然后继续执行然后函数,将传递给然后函数的参数函数放到微任务队列中:</p> <p> </p> <p>继续来,继续往下执行。碰到console.log(6),二话不说,直接压入栈中,执行,输出6,出栈,一气呵成。</p> <p>接着,引擎碰到了setTimeout函数,这家伙是个宏任务,但同时它会将传递给它的函数,加入到任务队列中:</p> <p> <img src=

JavaScript运行机制的示例分析