最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Promise面试题引起的JavaScript事件循环机制复习

    正文概述 掘金(和和和)   2021-05-12   504
    console.log('script start');
    
    setTimeout(async function() {
      console.log('setTimeout');
    }, 0);
    
    Promise.resolve().then(function() {
      console.log('promise1');
    }).then(function() {
      console.log('promise2');
    });
    
    console.log('script end');
    

    这个是查考JavaScript事件循环机制,你的答案是什么?

    正确答案是:script start, script end, promise1, promise2, setTimeout

    你答对了吗?

    我们来看看为什么

    • 整体 script 作为第一个宏任务进入主线程,遇到 console.log,输出 script start
    • 遇到 setTimeout,其回调函数被分发到宏任务的任务队列(Event Queue)中
    • 遇到 Promise,其 then函数被分到到微任务 Event Queue 中,记为 then1,之后又遇到了 then 函数,将其分到微任务 Event Queue 中,记为 then2
    • 遇到 console.log,输出 script end
    • 至此,任务队列(Event Queue)中存在三个任务,如下表:
    宏任务微任务
    setTimeoutthen1then2

    执行微任务,首先执行then1,输出 promise1, 然后执行 then2,输出 promise2,这样就清空了所有微任务 执行 setTimeout 任务,输出 setTimeout 至此,输出的顺序是:script start, script end, promise1, promise2, setTimeout

    看了答案之后,默默去复习了下,然后总结如下,小笔记。。。。

    想好好了解的话,去看看文末的连接就好了,下面就可以不看了。。。我是给自己记得小笔记,哈哈哈哈哈!

    “进程” 和 “线程”

    什么是进程?

    对操作系统来说执行一个任务就是一个进程。

    什么是线程?

    在一个进程上同时需要执行多个“子任务”。例:在使用word时,同时可以写字,拼写检查,打印等事情,在一个进程内部同时要干多件事,每件事都是一个线程。

    JS语言的特性:一门单线程非阻塞的语言

    单线程:是由于js最初的用途来决定的,与浏览器交互单线程意味着JS代码在执行的任何时候都是由主线程来处理所有任务
    非阻塞:JS在执行异步任务的时候无法立刻返回结果,需要花时间等待,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定的规则去执行回调函数。

    浏览器下JS引擎的事件循环机制

    JS在初次执行代码时:会将不同的变量存于内存中的不同位置。

    JS调用一个方法的过程:

    当调用一个方法时,js会生成与这个方法对应的执行环境(context),又叫做上下文,在执行环境中存在这个方法的私有作用域,上层作用域的指向(this对象),方法的参数。

    JS中“同步代码”是如何执行的?

    (1)、什么是“执行栈”?——用于方法排队等候的“暂存地”

    由于JS是单线程,同一时间只能执行一个方法,其余方法需要排队等候依次调用,所以这个排队等候的地方就是“执行栈”

    (2)、关于执行栈中的排队顺序

    当JS脚本第一次执行的时候,JS引擎会解析代码并将其中的“同步代码”顺序加入到执行栈,然后从头开始执行,如果当前执行的是一个方法,就会在执行栈中添加这个方法的执行环境,当方法执行完毕会退出执行环境并销毁,回到上一个方法的执行环境,这个过程反复执行,直到执行栈中的代码完全执行完毕。
    在一个方法的执行环境中,还可以调用别的方法,甚至可调用自己本身,其结果就是在执行环境中再添加一个执行环境,这个过程是可以无限循环下去的,除非发生“栈溢出”(即超过了使用内存的最大值,造成内存泄露)

    js中“异步代码”是如何执行的?

    (1)、事件队列(task queue)—— 存放异步事件的地方

    JS引擎遇到一个异步事件的时候,并不会一直等待结果,而会将这个事件挂起,继续执行“执行栈”中的其他任务,当这个异步事件返回结果后,js会将这个事件加入到另外一个队列中(即事件队列)
    异步事件放入到事件队列中不会立即执行,而是等待执行栈中所有的任务都执行完成,主线程处于闲置状态的时候,主线程会去查找事件队列中是否有任务,如果有,按照顺序依次调用
    主线程取出第一位事件,并把事件对应的回调函数放到执行栈中,然后执行同步代码,依次反复,这个过程就叫做“事件循环”。

    (2)、异步任务的类别:宏任务和微任务

    宏任务和微任务的执行顺序: 主线程会先查看微任务队列是否有事件存在,如果有,先逐一执行,直到微任务全部执行完毕然后再去执行宏任务,如果没有,再去宏任务中取出事件放入到执行栈中执行。

    任务队列

    所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。具体的可以用下面的图来大致说明一下:

    Promise面试题引起的JavaScript事件循环机制复习

    Event Loop (事件循环机制)

    同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue 。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。这个概念一定要背下来

    在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下:

    1.在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次)
    2.检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
    3.更新 render
    4.主线程重复执行上述步骤

    可以用一张图来说明下流程:

    Promise面试题引起的JavaScript事件循环机制复习

    然后,再看那个题,就理解啦啦啦啦啦啦

    引用

    深入浅出理解JS事件循环机制

    深入理解JavaScript事件循环机制


    起源地下载网 » Promise面试题引起的JavaScript事件循环机制复习

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元