Promise 执行顺序
console.log('1');
// setTimeout1
setTimeout(function() {
console.log('2');
// Promise2
new Promise(function(resolve) {
console.log('3');
resolve();
}).then(function() {
console.log('4')
// Promise3
new Promise(function(resolve) {
console.log('5');
// setTimeout3
setTimeout(function() {
console.log('6');
resolve();
})
}).then(function() {
console.log('7')
})
})
})
// Promise1
new Promise(function(resolve) {
console.log('8');
resolve();
}).then(function() {
console.log('9')
})
// setTimeout2
setTimeout(function() {
console.log('10');
// Promise4
new Promise(function(resolve) {
console.log('11');
// setTimeout4
setTimeout(function() {
console.log('12')
})
}).then(function() {
console.log('13')
})
})
console.log('14');
// 答案
// 1 8 14 9 2 3 4 5 10 11 6 7 12
执行规则描述
- 异步事件返回结果后会被放在异步任务队列中,根据类型会放在宏任务或微任务队列
- new Promie的
(resolve,reject) => {}部分, 属于同步代码 - 当 Promise resolve(状态 pending -> fulfilled),Promise 的
then(() => {})处理会放在微任务中 - 同理 Promise rejected(状态 pending -> rejected),Promise 的
catch(() => {})处理会放在微任务中
- new Promie的
- 当前执行栈为空时,先检查微任务是否存在,如果不存在再去检查宏任务
执行解答
- 初始状态
- 微任务队列:空
- 宏任务队列:空
- 当前执行栈:主线代码
- 输出 1
- setTimeout1 放入宏任务队列
- Promise1 中的同步代码执行
- 输出 8
- Promise1 resolve,then 回调放入微任务队列
- setTimeout2 放入宏任务队列
- 输出 14
- 当前状态
- 微任务队列:
[ Promise1.then ] - 宏任务队列:
[ setTimeout1, setTimeout2 ]
- 微任务队列:
- 当前执行栈: Promise1.then
- 输出 9
- 当前状态
- 微任务队列:
[] - 宏任务队列:
[ setTimeout1, setTimeout2 ]
- 微任务队列:
- 当前执行栈: setTimeout1
- 输出 2
- 执行 Promise2 中的同步代码
- 输出 3
- Promise2 resolve,then 回调放入微任务队列
- 当前状态
- 微任务队列:
[ Promise2.then ] - 宏任务队列:
[ setTimeout2 ]
- 微任务队列:
- 当前执行栈: Promise2.then
- 输出 4
- 执行 Promise3 中的同步代码
- 输出 5
- setTimeout3 放入宏任务队列
- 当前状态
- 微任务队列:
[ ] - 宏任务队列:
[ setTimeout2, setTimeout3 ]
- 微任务队列:
- 当前执行栈: setTimeout2
- 输出 10
- 执行 Promise4 中的同步代码
- 输出 11
- setTimeout4 放入宏任务队列
- 当前状态
- 微任务队列:
[ ] - 宏任务队列:
[ setTimeout3, setTimeout4 ]
- 微任务队列:
- 当前执行栈: setTimeout3
- 输出 6
- Promise3 resolve,then 回调放入微任务队列
- 当前状态
- 微任务队列:
[ Promise3.then ] - 宏任务队列:
[ setTimeout4 ]
- 微任务队列:
- 当前执行栈: Promise3.then
- 输出 7
- 当前状态
- 微任务队列:
[] - 宏任务队列:
[ setTimeout4 ]
- 微任务队列:
- 当前执行栈: setTimeout4
- 输出 12
Promise4 状态一直是 pending, 所以12不会输出
await 执行顺序
async function async1 () {
console.log(1)
// Promise1
new Promise((resolve) => {
console.log(2)
resolve();
}).then(function() {
console.log(3)
})
// Promise2
await new Promise((resolve) => {
console.log(5)
resolve();
}).then(() => {
console.log(6)
})
// await 1
console.log(7)
// Promise5
new Promise((resolve) => {
console.log(8)
resolve();
}).then(() => {
console.log(9)
})
}
// setTimeout1
setTimeout(() => {
console.log(10)
})
async function async2() {
console.log(11)
// Promise4
await Promise.resolve().then(() => {
console.log(12)
})
// await2
console.log(13)
}
async1()
// Promise3
new Promise((resolve) => {
console.log(14)
resolve();
}).then(() => {
console.log(15)
})
async2()
console.log(16);
// 答案
// 1 2 5 14 11 16 3 6 15 12 7 8 13 9 10
执行规则描述
- 执行遇到 await 让出线程, 阻塞后面代码
- await 语句是同步的,await 语句后面全部代码才是异步的微任务
- 只有运行完 await 语句,才把 await 语句后面的全部代码加入到微任务行列
- 在遇到 await promise 时,必须等 await promise 函数执行完毕才能对 await 语句后面的全部代码加入到微任务中
- await 会暂停 async 后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果
- 如果 await 后面不是promise, await会阻塞后面的代码, 先执行 async 外面的同步代码, 同步代码执行完毕后, 在回到async内部
执行解答
- 初始状态
- 微任务队列:空
- 宏任务队列:空
- 当前执行栈:主线代码
- 函数声明 async1
- setTimeout1 放入宏任务队列
- 函数申明 async2
- 执行 async1()
- 输出 1
- 执行 Promise1 中的同步代码
- 输出 2
- resolve, Promise1.then 放入微任务队列
- await Promise2
- 执行 Promise2 中的同步代码
- 输出 5
- resolve, Promise2.then 放入微任务队列
- await 让出线程
- 执行 Promise3 中的同步代码
- 输出 14
- resolve, Promise3.then 放入微任务队列
- 执行 async2()
- 输出 11
- Promise4 resolve, Promise4.then 放入微任务队列
- await 让出线程
- 输出 16
- 当前状态
- 微任务队列:[ Promise1.then, Promise2.then, Promise3.then, Promise4.then ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: Promise1.then
- 输出 3
- 当前状态
- 微任务队列:[ Promise2.then, Promise3.then, Promise4.then ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: Promise2.then
- 输出 6
- await1 后续代码放入微任务队列
- 当前状态
- 微任务队列:[ Promise3.then, Promise4.then, await1 ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: Promise3.then
- 输出 15
- 当前状态
- 微任务队列:[ Promise4.then, await1 ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: Promise4.then
- 输出 12
- await2 后续代码放入微任务队列
- 当前状态
- 微任务队列:[ await1, await2 ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: await1
- 输出 7
- 执行 Promise5 中的同步代码
- 输出 8
- resolve, Promise5.then 放入微任务队列
- 当前状态
- 微任务队列:[ await2, Promise5.then ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: await2
- 输出 13
- 当前状态
- 微任务队列:[ Promise5.then ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: Promise5.then
- 输出 9
- 当前状态
- 微任务队列:[ ]
- 宏任务队列:[ setTimeout1 ]
- 当前执行栈: setTimeout1
- 输出 10