微任务宏任务
- 将js执行分为 主线程,宏任务,微任务。 三种
- 执行的先后顺序是 主线程 —— 微任务 —— 宏任务
- 微任务包括:Promise,async await,MutaionObserver、process.nextTick(Node.js)
- 宏任务包括:setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js)
- js执行先进先出的原则
第一题
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
/**
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/
分析:
- 同步的主线程任务先执行
- new Promise的时候,定义时候要执行
- await 语句先执行,然后将 await后的语句放入任务队列中
- setTimeout宏任务最最后执行
第二题
new Promise((res,rej)=>{
console.log('promise')
res()
}).then(()=>{
console.log('then');
return new Promise((res2,rej2)=>{
console.log('promise2')
res2()
}).then(()=>{
console.log('then2')
})
}).then(()=>{
console.log('thenA')
}).finally(()=>{
console.log('finally')
}).then(()=>{
console.log('thenB')
})
setTimeout(()=>{
console.log('timeout')
},0)
/**
输出结果如下:
promise
then
promise2
then2
thenA
finally
thenB
timeout
*/
then里如果还有异步微任务,宏任务的执行依旧是等微任务结束后输出,所以timeout最最最后输出
Promise
链式调用
-
Promise的链式调用finally后依然可以调用then。同理finally后依然可以调用catch
Promise.all
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})
let pAll = Promise.all([Promise1, Promise2, Promise3])
pAll.then(()=>{
// 三个都成功则成功
}, ()=>{
// 只要有失败,则失败
})
Promise.race
顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})
let pRace = Promise.race([Promise1,Promise2,Promise3])
pRace.then(()=>{
//第一个Promise成功走这里
},()=>{
//第一个Promise失败走这里
})
题目:
new Promise((res,rej)=>{
console.log('promise')
res()
}).then(()=>{
console.log('then');
res()//这个then没有输出
rej()//调用catch
res()//如果catch后边有then,则调用catch之后的then
})
.then(()=>{
console.log('thenA')//没有调用
})
.catch(()=>{
console.log('catch')//被rej调用
})
.then(()=>{
console.log('thenB')//被rej后边的res调用
})
/**
输出结果
promise
then
catch
thenB
*/