假如你拿到这道面试题,让你写出执行结果,你给出的答案是什么?
setTimeout(function () {
console.log('1');
})
new Promise(function (resolve) {
console.log('2');
setTimeout(function () {
console.log('3');
})
resolve(true)
}).then(function () {
console.log('4');
})
console.log('5')
话不多说:从简单的例子来看
console.log(1);
setTimeout(()=>{
console.log(2);
})
Promise.resolve().then(()=>{
console.log(3);
})
console.log(4);
// 答案:1 4 3 2
先知道宏任务和微任务:
| 微任务 | 宏任务 |
|---|---|
| Promise.then()、Promise.catch()、Promise.finally()、async...await、process.nextTick(Node.js 环境) | Dom事件、ajax请求 、setTimeout、setInterval 、setImmediate(Node.js 环境) |
根据打印结果,可以发现微任务比宏任务执行的时间早,有没有想过为什么?其实dom执行前发生的是微任务,而dom执行后发生的是宏任务。执行时间:微任务 > DOM渲染 > 宏任务
那么文章最开始的段代码的执行结果究竟是怎么样的呢?先打印2,因为Promise本身是同步任务;再打印5;然后再打印4,因为Promise是微任务;再执行队列里面的宏任务1和3;所以执行结果是:2 5 4 1 3
console.log(1);
new Promise(function (resolve) {
console.log('2');
setTimeout(function () {
console.log('3');
})
resolve(true)
}).then(()=>{
console.log(4);
}).catch(()=>{
console.log(5);
}).finally(()=>{
console.log(6);
})
// 1 2 4 6 3
console.log(1);
new Promise(function (resolve) {
throw new Error(123)
resolve(true)
}).then(()=>{
console.log(4);
}).catch(()=>{
console.log(5);
}).finally(()=>{
console.log(6);
})
// 1 5 6
Tips: then和catch的执行需要看Promise是否执行有误,没错误执行then(),反之执行catch(),且finally()的打印结果一定在then和catch之后。把then、catch、finally当成一个整体就好了,只是有先后而已。