美文网首页
事件循环

事件循环

作者: 熬得萨菲 | 来源:发表于2020-02-06 19:42 被阅读0次

    JS 运行的环境称之为宿主环境

    执行栈: call stack, 一个数据解构,用于存放各种函数的执行环境,每一个函数执行之前,它的相关信息会加入到执行栈,函数调用之前,创建执行环境(上下文),然后加入到执行栈;函数调用之后,销毁执行环境(出栈)(上下文)。

    JS 引擎永远执行的是执行栈的最顶部。

    异步函数: 某些函数不会立即执行,需要等到某个时机到达后才会执行,这样的函数称之为异步函数。 比如事件处理函数。 异步函数的执行时机,会被宿主环境控制。

    浏览器宿主环境中包含 5 个线程:

    JS 引擎和 GUI 线程会相互等待,JS 引擎执行 GUI 等待,反之一样。

    1. JS 引擎: 负责执行执行栈的最顶部代码
    2. GUI 线程: 负责渲染页面
    3. 事件监听线程: 负责监听各种事件
    4. 计时线程: 负责计时
    5. 网络线程: 负责网络通信

    当上面的线程发生了某些事件,如果该线程发现,这件事情有处理程序,它会将该处理程序加入一个叫做事件队列的内存。当 JS 引擎发现,执行栈中已经没有了“任何”内容后,会将队列中的第一个函数加入到执行栈中执行。

    JS 引擎对事件队列的取出执行方式,以及与宿主环境的配合,称之为事件循环。

    事件队列在不同的宿主环境中有所差异,大部分宿主环境会将事件队列进行细分。 在浏览器中,事件队列分为两种:

    • 宏任务(队列): macroTask,计时器结束的回调、事件回调、http 回调等等绝大部分异步函数进入宏队列
    • 微任务(队列): MutationObserver(用于监听某个 dom 对象的变化),promise 产生的回调进入微队列。

    当执行栈清空时,JS 引擎首先会将微任务中的所有任务依次执行结束,如果没有微任务,则执行宏任务。

    递归: 就是遇到函数就一直创建上下文,等上下文创建完了,然后依次从栈顶执行上下文,最后依次销毁。 总的来说,就是一直创建执行上下文,一直销毁...。

    function getFeibo(n) {
        if (n === 1 || n === 2) {
            return 1;
        }
        return getFeibo(n - 1) + getFeibo(n - 2)
    }
    
    先遇到getFeibo(n - 1): 然后一直创建上下文,知道n=1, 之后执行上下文,执行完之后;
    后遇到getFeibio(n - 2): 过程一样
    
    

    相关文章

      网友评论

          本文标题:事件循环

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