zoukankan      html  css  js  c++  java
  • JavaScript 异步、栈、事件循环、任务队列

    概览

    我们经常会听到引擎和runtime,它们的区别是什么呢?

    • 引擎:解释并编译代码,让它变成能交给机器运行的代码(runnable commands)。
    • runtime:就是运行环境,它提供一些对外接口供Js调用,以跟外界打交道,比如,浏览器环境、Node.js环境。不同的runtime,会提供不同的接口,比如,在 Node.js 环境中,我们可以通过 require 来引入模块;而在浏览器中,我们有 window、 DOM。

    Js引擎是单线程的,如上图中,它负责维护任务队列,并通过 Event Loop 的机制,按顺序把任务放入栈中执行。而图中的异步处理模块,就是 runtime 提供的,拥有和Js引擎互不干扰的线程。接下来,我们会细说图中的:栈和任务队列

    现在,我们要运行下面这段代码:

    function bar() {
        console.log(1);
    }
    
    function foo() {
        console.log(2);
        far();
    }
    
    setTimeout(() => {
        console.log(3)
    });
    
    foo();


    它在栈中的入栈、出栈过程,如下图:

    任务队列

    Js 中,有两类任务队列:宏任务队列(macro tasks)和微任务队列(micro tasks)。宏任务队列可以有多个,微任务队列只有一个。那么什么任务,会分到哪个队列呢?

    • 宏任务:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.
    • 微任务:process.nextTick, Promise, Object.observer, MutationObserver.

    我们上面讲到,当stack空的时候,就会从任务队列中,取任务来执行。共分3步:

    1. 取一个宏任务来执行。执行完毕后,下一步。
    2. 取一个微任务来执行,执行完毕后,再取一个微任务来执行。直到微任务队列为空,执行下一步。
    3. 更新UI渲染。

    Event Loop 会无限循环执行上面3步,这就是Event Loop的主要控制逻辑。其中,第3步(更新UI渲染)会根据浏览器的逻辑,决定要不要马上执行更新。毕竟更新UI成本大,所以,一般都会比较长的时间间隔,执行一次更新。

    从执行步骤来看,我们发现微任务,受到了特殊待遇!我们代码开始执行都是从script(全局任务)开始,所以,一旦我们的全局任务(属于宏任务)执行完,就马上执行完整个微任务队列。看个例子:

    console.log('script start');
    
    Promise.resolve().then(() => {
        console.log('p 1');
    });
    
    setTimeout(() => {
        console.log('setTimeout');
    }, 0);
    
    var s = new Date();
    while(new Date() - s < 50); // 阻塞50ms
    
    Promise.resolve().then(() => {
        console.log('p 2');
    });
    
    console.log('script ent');
    
    
    /*** output ***/
    
    // one macro task
    script start
    script ent
    
    // all micro tasks
    p 1
    p 2
    
    // one macro task again
    setTimeout



    上面之所以加50ms的阻塞,是因为 setTimeout 的 delayTime 最少是 4ms. 为了避免认为 setTimeout 是因为4ms的延迟而后面才被执行的,我们加了50ms阻塞。在微任务中,process.nextTick 是一个特殊的任务,它会被直接插入到微任务的队首(当然了,多个process.nextTick 之间也是先入先出的),优先级最高。


    来源:https://segmentfault.com/a/1190000011198232
    
    
  • 相关阅读:
    stm32之不定长接收
    3、列表和列表项
    2、FreeRTOS任务相关API函数
    1、FreeRTOS移植
    5、根文件系统原理
    1、c++对c语言的扩展
    4、移植三星官方内核
    3、内核的启动过程
    2、内核的配置和移植
    iOS学习笔记19-地图(一)定位CoreLocation
  • 原文地址:https://www.cnblogs.com/liangzhixiaolaohu/p/8580372.html
Copyright © 2011-2022 走看看