Promise结合setTimeout
题目1
console.log('start')
setTimeout(() => {
console.log('time')
})
Promise.resolve().then(() => {
console.log('resolve')
})
console.log('end')`
输出:
start
end
resolve
time
分析:
- 执行同步代码:
- 检查微任务队列,将其中任务放入执行栈执行——
console.log('resolve');
,队列空 - 检查宏任务队列,将其中任务放入执行栈执行——
console.log('time')
同-->微-->宏
题目2
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
输出:
1
2
4
timeStart
timeEnd
success
分析:
- 执行同步代码:
- 检查微任务队列,为空
- 检查宏任务队列,依次执行
console.log("timerStart");
resolve("success");
console.log("timerEnd");
因为resolve是异步函数,会被放入微任务队列,当宏任务队列所有能执行的任务都取出后,开始新的循环
3. 执行栈为空,检查微任务队列,将微任务队列中的resolve放入执行栈执行,于是打印success
箭头函数能够保留它创建时的作用域,调用该作用域中的变量和函数,所以setTimeout改变执行流后,仍能调用resolve。
题目3
(1)
setTimeout(() => {
console.log('timer1');
setTimeout(() => {
console.log('timer3')
}, 0)
}, 0)
setTimeout(() => {
console.log('timer2')
}, 0)
console.log('start')
输出:
start
timer1
timer2
timer3
(2)
setTimeout(() => {
console.log('timer1');
Promise.resolve().then(() => {
console.log('promise')
})
}, 0)
setTimeout(() => {
console.log('timer2')
}, 0)
console.log('start')
输出:
start
timer1
promise
timer2
分析:
Promise.then是微任务,它会被加入到本轮中的微任务列表,而定时器timer3是宏任务,它会被加入到下一轮的宏任务中。
题目3
Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
console.log('timer2')
}, 0)
});
const timer1 = setTimeout(() => {
console.log('timer1')
Promise.resolve().then(() => {
console.log('promise2')
})
}, 0)
console.log('start');
输出:
start
promise1
timer1
promise2
timer2
分析:
- 执行同步代码:
- 检查微任务队列:
- 检查宏任务队列
- 检查微任务队列
- 打印promise2
- 检查宏任务队列
- 打印timer2
题目4
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
//console.log("success setTimeout");
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
输出:
promise1 Promise{<pending>}
promise2 Promise{<pending>}
//success setTimeout
Uncaught (in promise) Error: error!!!
promise1 Promise{<fulifilled> success}
promise2 Promise{<rejected> Error: error!!!}
分析:
- 执行同步代码
- 检查微任务队列,空
- 检查宏任务队列,空
- 1秒,微任务队列依然为空
- 1秒,定时器触发,执行
resolve("success");
- promise2的处理函数被放入微任务队列
- 将微任务队列的回调函数放入执行栈处理——
throw new Error("error!!!")
,抛出错误 - 2秒,微任务队列为空
- 2秒,将宏任务调入执行栈执行
console.log('promise1', promise1)
console.log('promise2', promise2)
此时promise1-->fulfilled,promise2-->rejected
可以提前给期约的处理函数赋值,但只有当状态转变时,回调函数才会进入微任务队列
如果先转状态,那么给相应处理函数赋值时,回调函数就会进入微任务队列
题目5
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("success");
console.log("timer1");
}, 1000);
console.log("promise1里的内容");
});
const promise2 = promise1.then(() => {
throw new Error("error!!!");
});
console.log("promise1", promise1);
console.log("promise2", promise2);
setTimeout(() => {
console.log("timer2");
console.log("promise1", promise1);
console.log("promise2", promise2);
}, 2000);
输出:
promise1里的内容
promise1 Promise{<pending>}
promise2 Promise{<pending>}
timer1
Uncaught (in promise) Error: error!!!
timer2
promise1 Promise{<fulfilled> success}
promise2 Promise{<rejected> Error error!!!}
分析:
与上一题类似
感谢阅读。
百炼成钢!!!
参考:
【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理)
《JavaScript高级程序设计》(第四版)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。