• js~eventLoop 事件循环


    事件循环的概念:

    因为js是单线程的。所以js是从上至下按顺序运行下去的,顺序执行代码,那么,如果js代码中间向后台发送一个ajax请求,就要等到请求等到结果后才会继续向下执行。如果请求耗时过长,或者请求报错,会导致用户体验不好。因此,就有了同步任务、异步任务的区别。

    同步任务和异步任务在js中是如何执行的呢?js的代码运行会形成一个主线程和一个任务队列。主线程会从上到下一步步执行我们的js代码,形成一个执行栈。同步任务就会被放到这个执行栈中依次执行。而异步任务被放入到任务队列中执行,执行完就会在任务队列中打一个标记,形成一个对应的事件。当执行栈中的任务全部运行完毕,js会去提取并执行任务队列中的事件。这个过程是循环进行的,这就是我们今天想要了解的event loop

    因为js的event loop机制,所以大家不要认为setTimeOut设置的事件到了延迟时间就是被执行。如果你的执行栈任务没有被全部执行完,清空。setTimeOut事件执行的时间很有可能是要大于你设置的延时参数。

    宏任务微任务:

     

    异步任务之间是有执行优先级的区别的。不同的异步任务会被分为两类,微任务和宏任务

     

    宏任务: 需要多次事件循环才能执行完,事件队列中的每一个事件都是一个宏任务。

     

    常见的宏任务:定时器,延时器,ajax, 交互事件

     

    微任务: 微任务是一次性执行完的。微任务通常来说是需要在当前task执行结束后立即执行的任务,例如对一些动作做出反馈或者异步执行任务又不需要分配一个新的task,这样便可以提高一些性能。

     

    常见的微任务:promise.then(),  process.nextTick , MutationObserver

        

    宏任务中包含微任务时,按照顺序循环执行   

    new Promise((reslove,reject)=>{
                console.log("romise start")
                reslove("data")
            }).then((res)=>{ console.log(res) })
    
            setTimeout(()=>{
                console.log("settimeout start")
                new Promise((reslove,reject)=>{
                    console.log("romise1111 start")
                    reslove("data romise11")
                }).then((res)=>{console.log(res)})
                console.log("settimeout end")
            },0)
    
            setTimeout(()=>{
                console.log("settimeout222 start")
                new Promise((reslove,reject)=>{
                    console.log("romise2222 start")
                    reslove("data romise2222")
                }).then((res)=>{console.log(res)})
                console.log("settimeout222 end")
            },0)
    console.log(10000)

    以上代码执行效果如下:

    romise start
    10000
    data

    首先程序进入到代码块执行scrit主线程任务 romise start  , 10000,然后执行了Promise.then()  // data


    settimeout start
    romise1111 start
    settimeout end
    data romise11

    延时器属于宏任务,但是延时器里面还有同步任务和微任务,首先执行完了同步任务 settimeout start , romise1111 start , settimeout end,然后执行微任务。

    第一个宏任务执行完毕了,接着开始执行第二个宏任务。

    settimeout222 start
    romise2222 start
    settimeout222 end
    data romise2222

     

    微任务中混合宏任务 相互混合

    {
                console.log(1);
    
                setTimeout(() => {
                    console.log(2);
                })
    
                new Promise((resolve) => {
                    console.log(3)
                    resolve()
                }).then(() => {
                    setTimeout(() => {
                        console.log(4);
                    })
                }).then(() => {
                    console.log(5)
                })
    
                console.log(6)
    
                setTimeout(() => {
                    console.log(7)
                    new Promise(resolve => {
                        console.log(8)
                        setTimeout(() => {
                            console.log(9)
                        })
                        resolve()
                    }).then(() => {
                        console.log(10)
                    })
                }, 500)
    
                new Promise(resolve => {
                    console.log(11)
                    resolve()
                }).then(() => {
                    console.log(12)
                    setTimeout(() => {
                        console.log(13)
                    }, 0)
                })
                
                console.log(14)
                // 1 3 6 11 14 主线程
                // 12 5
                // 宏任务 2 4 13 7 8 10 9
            } 

     

  • 相关阅读:
    SqlServer2008启动不了的问题
    .exe 不包含适合入口点的静态“Main”方法
    两种常用的序列化
    异或运算^
    SqlServer数据库实现C#中的split功能
    遍历电脑下面所有文件--递归
    ExecuteNonQuery引发了System.ArgumentException类型异常
    JQuery属性过滤(转)
    SQL SERVER 执行远端数据库的SQL命令
    马云:做一个静静的观察者 能学到更多
  • 原文地址:https://www.cnblogs.com/rose-sharon/p/12427214.html
Copyright © 2020-2023  润新知