复习Promise相关的面试题时,刷到了一个文章【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理) 本文是我看完之后的笔记。
异步相关的问题,基础知识是事件循环(Event Loop)。在分析代码的时候,执行栈、微任务队列、宏任务队列,这三个队列要确定好。
1.Promise new 实例化的参数函数,是立即执行的
let P = new Promise((resolve, reject) => {
// 立即执行
console.log("立即执行")
})
2. 实例化出来的p对象的状态
let P = new Promise((resolve, reject) => {
resolve() // p的状态就是 fulfilled 成功
reject() // p的状态就是 rejected 失败
// 如果没有执行 resolve() 和 reject() 的话 p的状态就是 pending状态
})
// 注意链式操作的时候 p1的值是 then 的return值。
const p1 = new Promise((resolve) => {
setTimeout(() => {
resolve('resolve3');
console.log('timer1') // 3
}, 0)
resolve('resovle1');
resolve('resolve2');
}).then(res => {
console.log(res) // 1 resovle1
setTimeout(() => {
console.log(p1) // 4 fulfilled resovle1
// 这里判断错了,因为 这个then 没有 return 值
}, 1000)
}).finally(res => {
console.log('finally', res) // 2 finally undefined
return 1
})
3. return new Promise() 是否执行
let p = function() {
return new Promise(() => {})
}
p().then(() => {}) // 只有在P函数执行的地方,才会执行Promise实例化
4. setTimeout 的执行会放在宏任务队列,Promise().then().catch() 是放在微任务队列
比如有宏任务事件1,宏任务事件2, 如果在宏任务事件1里面又添加了一个微任务1,那么微任务1比宏任务2先执行 juejin.cn/post/684490…
-
如果返回的 Promise 是自己的话,就会形成一个嵌套,会报错的
const promise = Promise.resolve().then(() => { return promise; }) // promise.catch(console.err)
6.then 和 catch 的参数期望是 fn ,如果不是的话发生值穿透将 resove() 值传递到最后一个 then里面
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log) // 1
7..all([]) 可以并行执行多个异步任务。
//一组异步任务,如果有一个异常就不会进入 then()。
//catch 会捕获最先跑出来的reject()
Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
8. await fn(); fn()函数会立即执行,之后代码的执行就放在了,微任务队列中。之后的代码会阻塞。
-
await new Promise((resolve, reject) => {}) // 如果没有状态的话。 await 后面的代码是不会执行的。如果 new Promise(...) 并不会阻塞后面的代码执行
// 不会阻塞 async function async1() { console.log("async1 start"); new Promise((resolve, reject) => { console.log('promise') }) console.log("async1 end"); return '1' } async1().then((res) => { console.log(res) }) // 会阻塞 async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1') }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async1().then(res => console.log(res)) console.log('srcipt end')
10.如果在async函数中抛出了错误,则终止错误结果,不会继续向下执行。
async function async1 () {
await async2();
console.log('async1');
return 'async1 success'
}
async function async2 () {
return new Promise((resolve, reject) => {
console.log('async2')
reject('error')
})
}
async1().then(res => console.log(res))
11.finally 在 finally2之后 .then() 和 .finally() 会返回一个promise,这种链式调用,就相当于把链式之后的代码放进微任务列表中。
Promise.resolve('1')
.then(res => {
console.log(res)
})
.finally(() => {
console.log('finally')
})
Promise.resolve('2')
.then(res => {
console.log('finally2后面的then函数', res)
})
.finally(() => {
console.log('finally2')
return '我是finally2返回的值'
})
//1
//finally2后面的then函数 2
//finally
//finally2