美文网首页
js执行任务流程最详细讲解

js执行任务流程最详细讲解

作者: 扶得一人醉如苏沐晨 | 来源:发表于2022-05-30 11:01 被阅读0次

    1、首先我们要明白一个概念,js它是单线程的一门语言。

    它是基于事件循环的。事件循环大致分为以下几个步骤:

    所有同步任务都在主线程上执行,形成一个执行栈

    主线程之外,还存在一个"任务队列"(task queue)。

    只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

    一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。主线程不断重复上面的第三步。



    因为console.log是同步代码,所以会立刻放到主线程中执行,当我们异步请求数据时,console.log()执行代码未放到异步请求中,就会在主线程中执行,自然获取不到数据,而如果用setTimeout包裹console.log(),它会放到我们的任务队列里边,等待主线程的活干完了,再拿到主线程执行,如下代码所示:


    任务队列里面又分为宏任务与微任务

    微任务,也称job

           通常用于在当前正在执行的脚本之后直接发生的事情,比如对一系列的行为做出反应,或者做出一些异步的任务,而不需要新建一个全新的task。只要执行栈没有其他javascript在执行,在每个task结束时, 微任务队列就会在回调后处理。在 微任务 期间排队的其他 微任务 将被添加到这个队列的末尾

          常见的 微任务 有 MutationObsever 、 Promise.then  、$nextTiock

    宏任务

           作用是为了让浏览器能够从内部获取javascript / dom的内容并确保执行栈能够顺序进行。调度是随处可见的,例如解析HTML,获得鼠标点击的事件回调等等。

           常见的 宏任务 有 setTimeout、MessageChannel、postMessage、setImmediate;



    因为promise.then  $nextTick()是个微任务,setTimeout是个宏任务,所以先输出promise。


    2.定时器的任务编排

    这里我们发现,定时器虽然是异步任务,但js执行是单线程,当时间结束后,定时器会被放到任务队列挂着,当主线程执行时间过长,定时器时间到了会先挂起来,一旦主线任务结束,就立即执行定时器。

     如,一个for循环执行结束需要5000ms而定时器执行2000ms,2000ms过了,定时器就会被放入任务队列,5000ms的主线任务结束后,立即执行定时器,而不是在等2000ms执行定时器回调。


    3.Promise微任务处理逻辑

    Promise 是同步代码立刻执行,然后执行下面的同步代码console.log(‘hello’),同步代码执行完后到微任务里面找到promise.then()的console.log() 来执行,最后执行宏任务setTimeout

    接下来我们看如下代码,看起来有点复杂,但是我们记住一个原则,“先执行同步代码,再执行微任务,最后执行宏任务”,这样就会清晰很多

    4、DOM渲染任务

    如下代码,我们在渲染DOM 前执行了一个非常耗时的for循环,因为DOM渲染也是一个同步任务,而for循环在DOM渲染之前,所以会将for循环执行完后再渲染DOM。

    这时候页面会有很长一段时间的空白,然后才渲染h1标签和文字

    解决办法:

    将js代码放到最后,这样就完美解决了



    5.任务共享内存

    时间到了,会将其回调任务放到我们的任务队列当中,虽然时间一样,但是还是遵循从上而下的规则,首先输出中的++i,然后再加一次

    6、三角塔构成

    相关文章

      网友评论

          本文标题:js执行任务流程最详细讲解

          本文链接:https://www.haomeiwen.com/subject/fmznprtx.html