事件循环2(微任务 和宏任务)

JS是单线程,一次只能执行一个任务,当有一个耗时很长时,有一个在后面等待,会造成堵塞,异步的目的就是处理堵塞,提升性能。

一、promise对象

promise调用内部函数。

promise有三种对象:

1.pending:待定,未初始化

2.resolved:异步成功

3.rejected:异步操作失败

promise对象状态改变:

1.从pending到resolved

2.从pending到rejected

参数 resolve和reject无论哪个值被调用,状态都不可以撤销,被调用后,then方法返回这个被调用的值。

console.log("你好");
    let a=new Promise(function(resolve, reject){
        console.log("第一个对象");
        setTimeout(function(){
            resolve("aha!");
            console.log("huhu");
        },1000);
    })
    setTimeout(()=>{
        console.log("再见");
    },0)
    console.log(45);
//输出:你好 第一个对象  45 再见 aha!

 

二、宏任务和微任务 

 1.宏任务

 可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。

(macro)task->渲染->(macro)task->...
//完成第一个宏任务之后开始渲染,之后再执行下一个任务

宏任务包括:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

2.微任务

当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。

微任务包括:

Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)

 过程:

  • 执行一个宏任务(栈中没有就从事件队列中获取)
  • 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
  • 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  • 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
  • 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
 console.log("1");
 new Promise(function(resolve,reject){
     console.log(2);
     resolve();
 }).then(function(){
     console.log(3);
 });
 setTimeout(function(){
     console.log(4);
 })
 console.log(5);
//输出:1 2 5 3 4

 

posted @ 2021-09-28 15:43  陌菡  阅读(49)  评论(0)    收藏  举报