2021,搞懂宏任务和微任务(趣味)

1,378 阅读6分钟

没错,我又在大家都放假的时候来更新文章了

前言

入门文章,在看其他大佬文章时候,整理,总结了一些知识点。做成文章输出强化记忆。

1、介绍宏任务和微任务

简单介绍,并且只列出一些常用和本文用到的。

宏任务

宏任务:script 、setTimeout、setInterval,setImmediate等。

微任务

微任务:Promise.then()或catch()、async函数中的await紧跟函数/语句之后的内容(具体请看栗子)、nextTick(例如vue,node等)

执行顺序

进入script标签(或者是js文件),此时所有的js代码默认为一个宏任务(记作:宏1);然后宏任务执行中遇见的Promise.then()或者是catch()加入到微任务(记作:微1);遇见setTimeout加入到下次宏任务(记作:宏2) ; 代码的执行顺序为:宏1->微1->宏2->微2……

看不懂没关系,题海战术开始(背景音乐起……)

2、Promise相关

栗子1

new Promise( resolve => {
  console.log(1);
}).then( res => {
  console.log(2);
});
console.log(3);

栗子2

new Promise( resolve => {
  console.log(1);
  resolve()
}).then( res => {
  console.log(2);
});
console.log(3);

栗子3

new Promise( resolve => {
  console.log(1);
  resolve()
}).then( res => {
  console.log(res);
});
console.log(3);

栗子4

new Promise( (resolve,reject) => {
  console.log(1);
  resolve(2)
  resolve(3)
  reject(4)
}).then( res => {
  console.log(res);
}).catch( res => {
  console.log(res)
});
console.log(3);

知识点解析

1、new Promise里面内容直接运行的 2、.then是否执行和promise中是否有返回值相关(resolve或者是return)。 3、.then执行时,会等之前宏任务执行完成后,延迟执行,并且参数和resolve返回的参数相关联 4、.Promise中resolve的结果,一经确认就不再修改

所以,你是否要重新思考下上面四道题目的答案?

大佬:你在教我做事???

没错,当然是自信的往下翻了!!!

答案

栗子1:1,3

栗子2:1,3,2

栗子3:1,3,undefined

栗子4:1,3,2

大佬1:就这?

大佬2:就这?

大佬3:就这?目侧题目很简单。

大佬4:题目简单,所以这人智商低,确认完毕。

3、Promise和setTimiout结合

接下来难度增加了,毕竟我小学三年级马上毕业了,不能太简单。

栗子1

console.log('start');
new Promise( (resolve,reject) => {
  console.log('promise');
  resolve('then')
  reject('reject')
  setTimeout( () => {
    console.log('setTimeout')
  },)
}).then( res => {
  console.log(res);
}).catch( res => {
  console.log(res)
});
console.log('end');

栗子2

new Promise( (resolve,reject) => {
  setTimeout( () => {
    console.log('setTimeout')
    resolve('then')
  },)
  resolve('then')
}).then( res => {
  console.log(res);
})


栗子3

new Promise( (resolve,reject) => {
  console.log('promise')
  setTimeout( () => {
    console.log('setTimeout')
    resolve('then')
  },)
}).then( res => {
  console.log(res);
})

栗子4

var promise1 = ()=>(
  new Promise( (resolve,reject) => {
    console.log('promise1');
    promise2().then( res => {
      console.log(res)
    })
    setTimeout( () => {
      console.log('setTimeout');
      resolve('then1');
    },);
  })
);

var promise2 = () => (
  new Promise( resolve =>{
    console.log('promise2');
    resolve('then2');
  })
);

promise1().then( res => {
  console.log(res);
});

刚刚谁骂我智商低,题简单的,来,给你个红buff,网通一,蓝色方,f6旁边的草丛。

知识点解析

详细分析一下栗子4的过程执行:

进入js文件,所有的代码默认为宏1任务。

JavaScript开始执行(宏1),promise1函数,promise2函数声明提前,

1、执行promise1函数内容(宏1):进入new Promise,控制台打印promise1,

2、执行到promise2函数:进入 new Promise,控制台打印promise2,promise2的new Promise进入resolved状态,返回值是then2

3、promise2的.then()函数放入微任务(微1),

4、执行到setTimeout定时器,将定时器所有内容放入宏任务宏2,等待执行

5、promise1函数执行完毕,继续执行到 promise1的.then()函数,发现promise1没有返回任何状态(没有resolve或者return),故不执行。

6、宏1执行完毕,开始执行微1任务,

7、微1执行promise2.then(),控制台打印then2

8、宏2执行setTimiout函数,控制台打印setTimeout,并且让promise1进入了resolved状态,

9、promise1.then()发现有了resolve状态,所以加入微任务(微2),

10、执行微2任务,控制台打印then1

控制台:promise1,promise2,then2,setTimeout,then1

想了想,还是画一下图吧(图真难画)

答案

栗子1:start,promise,end,then,setTimeout

栗子2:then,setTimeout

栗子3:promise,setTimeout,then

栗子4:promise1,promise2,then2,setTimeout,then1

大佬1:我错了一道题。

大佬2:楼上垃圾(偷偷藏错题本)。

大佬3:楼上都垃圾。

大佬4:楼上都垃圾,我最XX(已知:XX === 明年生肖)。

写到这里已经累成狗了,在纠结要不要继续写下去,因为我小学三年纪的知识已经用完了(刚刚得到了一个噩耗:我们联合办公的小伙伴一个小时后提前下班放假,而我们还得呆两天)。

4、Promise和async/await结合

怎么办,已经用到了初一的知识了,而我不会,怎么胡编乱造一波?

对了,看看大佬们的《5分钟入门初一》

栗子1

console.log(1)
async function async1() {
  console.log(2);
  await async2();
  console.log(3);
}
async function async2() {
  console.log(4);
}
async1();
console.log(5)

栗子2

async function async1() {
  console.log(1);
  await new Promise( resolve => {
  	console.log(2)
    resolve(5)
  }).then( res => {
  	console.log(3)
  }).finally( res => {
  	console.log(4)
  });
  console.log(5);
}
async1();
console.log(6)

栗子3

async function async1() {
  console.log(1);
  await new Promise( resolve => {
  	console.log(2)
  }).then( res => {
  	console.log(3)
  }).finally( res => {
  	console.log(4)
  });
  console.log(5);
}
async1();
console.log(6)

栗子4

async function async1 () {
  console.log('1');
  await new Promise(resolve => {
    console.log('2')
    resolve('3')
  })
  console.log('4');
  return '5'
}
console.log('6')
async1().then(res => {
  console.log(res)
})
new Promise(resolve => {
  console.log('7')
  setTimeout(() => {
    console.log('8')
  })
})

知识点解析

1、await紧跟函数(语句)之后的内容将被延迟执行(相当于一个微任务,放在此次宏任务执行完毕后执行)

2、await紧跟函数(语句)如果是一个promise函数并且没有返回值(resolve/reject)时候,promise之后紧跟内容将不会被执行,直到promise函数有返回值

答案

栗子1:1,2,4,5,3

栗子2:1,2,6,3,4,5

栗子3:1,2,6

栗子4:6,1,2,7,4,5,8

大佬1:我错了三道题。

大佬2:我也错了一道题(实际错了两道)。

大佬3:楼上有我一半水平了,现在年轻人呀……(偷偷藏错题本)。

大佬4:楼上垃圾,题太简单

5、组合题

终于见到了boss关卡,

面对巨龙吧,勇士。

如果你能杀掉恶龙,那么你就是下一个恶龙。

栗子1

var promise1 = () => (
  new Promise( resolve => {
    console.log(1);
    var promise2 = new Promise( resolve => {
      console.log(2);
      setTimeout( ()=>{
        console.log(3);
        resolve();
      },0);
    });
    resolve()
    promise2().then( ()=> {
      console.log(4);
    });
  })
  
);
promise1().then( () => {
  console.log(5);
});
console.log(6);

栗子2

const promise1 = new Promise( (resolve) => {
  setTimeout( () => {
    resolve(1);
    console.log(2)
  }, 0)
  resolve(3);
  resolve(4);
}).then(res => {
  console.log(res)
  setTimeout(() => {
    console.log(5)
  }, 1000)
}).finally(res => {
  console.log('finally', res)
})

栗子3

async function async1 () {
  console.log('1');
  await new Promise(resolve => {
    console.log('2')
    resolve('3')
  })
  console.log('4');
  return '5'
}
console.log('6')
async1().then(res => {
  console.log(res)
})
new Promise(resolve => {
  console.log('7')
  setTimeout(() => {
    console.log('8')
  })
})

答案

栗子1:1,2,6,5,3

栗子2:3,2,5

栗子3:6,1,2,7,4,5,8

大佬1:自闭ing。

大佬2:放开我,我还能做题,放开我,你不要过来呀

大佬3:感觉第三题怪怪的,。

大佬4:为什么要拿做过的题目来充数,你以为我傻吗,你浪费我一下午时间,你信不信我%……*&%%&¥%#……%(省略一万句祝福新年的话)。

6、总结

学无止境。

我曾踏足山巅,也曾跌落低谷,二者都让我受益良多。 ————宝石(LOL)

新年好。