事件循环机制

103 阅读3分钟

浏览器的主要进程

  • Browser进程
  • 第三方插件进程
  • GPU进程
  • 渲染进程

渲染进程中的主要线程

  • GUI渲染进程

  • JS引擎线程(主要线程)

  • 事件触发线程

    事件触发线程管理着一个 事件队列[fn1,fn2,success],队列中包含已触发事件的回调函数,等待被JS引擎线程空闲时来调用

  • 定时器线程

  • 异步http请求线程

    当我们发送ajax请求时,等待响应状态改变/响应结果都是异步http请求线程在处理; 当请求完成时,触发事件,事件触发线程将对应的回调函数加入事件队列

页面渲染流程

  • 从上到下解析html标签,构建DOM树
  • 解析CSS样式,构建CSSOM样式树
  • 根据DOM树和CSSOM样式树,计算生成渲染树
  • 根据渲染树渲染页面

事件循环机制(Event loop)

  • js引擎解析代码,将同步任务按照执行顺序加入执行栈/调用栈(call stack),然后按照顺序依次执行
  • js解析到异步任务时,不会立即执行、等待异步的结果,而是交给其他线程来处理,继续执行同步任务
  • 其他线程处理完异步任务后,对应的回调函数加入事件队列,等待js引擎空闲时来执行
  • 异步任务的回调函数在调用时,又有其他同步、异步任务,重复上述步骤

promise

    setTimeout(()=>{// f1
        console.log( 0 );
    },0);
    new Promise((resolve,reject)=>{// f2
        console.log( 1 );
        resolve();
    }).then(()=>{// f3
        console.log( 2 );
        new Promise((resolve,reject)=>{// f4
            console.log( 3 );
            resolve();
        }).then(()=>{// f5
            console.log( 4 );
        }).then(()=>{// f6
            console.log( 5 );
        })
    }).then(()=>{// f7
        console.log( 6 );
    });
    new Promise((resolve,rejpect)=>{// f8
        console.log( 7 );
        resolve();
    }).then(()=>{// f9
        console.log( 8 );
    });
    (异步)微队列:[f3,f9,f5,f7,f6]
           宏队列:setTimeout f1
    new Promise()//f2
      console.log( 1 );
      resolve();  状态  -> fulfilled -> 将f3加入微队列
    new Promise()//f8
      console.log( 7 );
      resolve();  状态  -> fulfilled -> 将f9加入微队列
    此时js空闲,优先处理微队列,取出f3
      console.log( 2 );
      new Promise()
        console.log( 3 );
        resolve();  状态  -> fulfilled -> 将f5加入微队列
    此时f3执行完成(fulfilled),将f7加入微队列
    此时js空闲,优先处理微队列,取出f9
      console.log( 8 );
    此时js空闲,优先处理微队列,取出f5
      console.log( 4 ); 
    由于return undefined  -> fulfilled -> 将f6加入微队列
    此时js空闲,优先处理微队列,取出f7
      console.log( 6 );
    此时js空闲,优先处理微队列,取出f6
      console.log( 5 );
    此时js空闲,处理宏队列
    console.log( 0 )
    结果:1,7,2,3,8,4,6,5,0

异步函数

    async function async1(){
        console.log( 1 );
        let res = await async2();
        console.log( 2 );
    }
    async function async2(){
        console.log( 3 );
    }
    console.log( 4 );
    setTimeout(()=>{// f1
        console.log( 5 );
    });
    async1();
    new Promise((resolve,reject)=>{// f2
        console.log( 6 );
        resolve();
    }).then(()=>{// f3
        console.log( 7 );
    });
    console.log( 8 );
    微队列:[await,f3]
    宏队列:setTimeout f1
 console.log( 4 );
 async1();
   console.log( 1 );
     //let res = await async2();
     async2();
     console.log( 3 );
 await 会跳出当前的执行流,继续执行后面的同步程序
 await 返回的是一个promise对象,加入微队列
 new Promise()
   console.log( 6 );
   resolve(); 状态  -> fulfilled -> 将f3加入微队列
 console.log( 8 );
 此时js空闲,优先处理微队列,继续执行await后的程序
   console.log( 2 );
 此时js空闲,优先处理微队列,取出f3
    console.log( 7 );
 此时js空闲,处理宏队列
   console.log( 5 );
 结果:4,1,3,6,8,2,7,5